• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

Keeping code out of the Servlet

 
Ranch Hand
Posts: 15304
6
Mac OS X IntelliJ IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
How much code should we move outside of the servlet. For example, I have a class called ValidateUser which I pass the username and password to a method that returns a boolean. In this method I do all my database lookups and what not, then just return true or false depending on if the user is valid.

In my servlet I extract the username and password from the request and I also handle adding information to the HttpSession if the user was valid.

What I am wondering is, is it bad design to move even the Request extraction and the HttpSession handling into the ValidateUser class? Or should all javax.servlet.* operations be done in the servlet class itself.

I've been doing it the way I described above for a while, but wondered if I should be doing it differently or if it really matters.

How much beyond forwarding and redirecting should a servlet do?
 
Sheriff
Posts: 67746
173
Mac Mac OS X IntelliJ IDE jQuery TypeScript Java iOS
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The way I separate things is I imagine that the business layer could be used for either a web interface, a Swing program, or a command line program.

In your example, this means that the API that performs the validation should be completely UI-agnostic, and that any code that could be shared among different UI paradigms for the same program are moved out of the servlet.
 
Author and all-around good cowpoke
Posts: 13078
6
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
After wrestling for years with servlets that just get bigger and bigger, I have taken to grabbing the request parameters as a Map with getParameterMap and just handing that plus the output stream to a "worker" class method typically called "doTheNextThing". An instance of the "worker" class goes in the session, and thats about it.

This has the advantage that I can test "doTheNextThing" with simulated input outside the servlet environment.

So my answer to "How much code should we move outside the servlet?" is "as much as you conveniently can."
Bill
 
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, all of it.

No actually, I think this is the kind of post that I post the most on JavaRanch. It is my motto, my creed, my live by it or die saying.

Servlets, EJBs, Daemon Threads, Listener Servers, and the ilk. The main interface classes to the "outside world" should all be Facade's. They should get the call outside of themselves as soon as possible. They should only do what they are created to do. KEEP IT SIMPLE.

Ok, so in my opinion that means that you should do what Bill said. He is basically saying that the Servlet is there for the context, to get the Response and Request objects, to get the parameters sent with the Request and to return the response.

All the other code should be kept out of the Servlet, and in other plain old Java objects. Now you can test those POJOs outside of any container, you can reuse them in any application. Your Servlet is now the lowest risk object you have, so sometimes you don't even have to Unit Test them, because they all do the same thing. You can even end up creating a Controller Servlet, that will hand it off to a class that determines who actual handles the Request coming in. Kind of sounds like Struts and JSF frameworks.

Good Luck and Keep it Simple. If your UML diagrams don't look pretty, balanced and doesn't have good Feng Shui, then something is wrong.

Mark
 
Gregg Bolinger
Ranch Hand
Posts: 15304
6
Mac OS X IntelliJ IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Thanks a lot for the info guys. I have a question. From what Bear states, it sounds as if he wouldn't pass the request and response objects to the "POJO's" (I hate that acronym). But Bill and Mark both suggest this would be the thing to do.

I would assume that unit testing wouldn't be too bad on the POJO's either way, but unit testing without requiring HTTP would be easier. Also, keeping HTTP out of the POJO's would also allow them to be more widely used in other non-web applications, am I right?
 
Ranch Hand
Posts: 1211
Mac IntelliJ IDE
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What works quite nicely for me is that I have a 'Request Controller' class, which I create as a session scope bean. The controller JSP or Servlet passes over the request and session objects to this class, which does any HTTP related processing, and then invokes methods on business logic classes.

So, the servlet contains virtually no code, all the Servlet API code is limited to the 'Request Controller' class, and the classes implementing business logic have no Servlet API dependent code.

My inspiration (theft ) for this kind of arrangement came from the Wrox J2EE Programming book, I think it was the chapter on How to write maintanable JSP's.
 
Gregg Bolinger
Ranch Hand
Posts: 15304
6
Mac OS X IntelliJ IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The controller JSP or Servlet passes over the request and session objects to this class, which does any HTTP related processing, and then invokes methods on business logic classes.

How does this class determine what HTTP related processing to perform and what methods to invoke?
 
Mark Spritzler
ranger
Posts: 17347
11
Mac IntelliJ IDE Spring
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

I have a question. From what Bear states, it sounds as if he wouldn't pass the request and response objects to the "POJO's" (I hate that acronym). But Bill and Mark both suggest this would be the thing to do.



Actually I wasn't proposing that you pass the request and response objects to the POJOs.

Yuo want to get what you need out of the request, and that is what you would pass to the POJO. If you pass the Request object to a POJO, then the POJO now knows that it is tied to a Servlet, which makes the POJO too tightly coupled, like you said.

And the POJO can return information that the Servlet would pass through the Response object.

Mark
 
Ranch Hand
Posts: 101
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Mark Spritzler:
You can even end up creating a Controller Servlet, that will hand it off to a class that determines who actual handles the Request coming in. Kind of sounds like Struts and JSF frameworks.



Or you could just use one servlet per request and have the web container, via <servlet-mapping> tags in web.xml do the work.

I am not a big fan of web frameworks mainly because when what I consider good practice is followed, they aren't really needed.

As suggested here, the 'front end' (web, swing, ejb, webservices, command line) module should only act as a fascade or translator to the actual meat of your app. Each of these should handle the protocol required to communicate as well as take the user's input and prepare/parse it into what the actual business methods require.

If all the web app is doing is getting some info out of the Application Context, Session, Request or Page, passing it off to a POJO that does the work and then forwarding to a JSP to show the results, I don't really think a framework is called for.

Like suggested, keep it simple. Total seperation of the logic from the presentation (Servlets & STRUTS are the bridge between View and Controller) will only make you a happy boy down the road.
 
Gregg Bolinger
Ranch Hand
Posts: 15304
6
Mac OS X IntelliJ IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Or you could just use one servlet per request and have the web container, via <servlet-mapping> tags in web.xml do the work.

I am not a big fan of web frameworks mainly because when what I consider good practice is followed, they aren't really needed.


Oh no. Here we go again.

Actually I wasn't proposing that you pass the request and response objects to the POJOs.

Yuo want to get what you need out of the request, and that is what you would pass to the POJO. If you pass the Request object to a POJO, then the POJO now knows that it is tied to a Servlet, which makes the POJO too tightly coupled, like you said.

And the POJO can return information that the Servlet would pass through the Response object.

Mark


Oh, ok. I misunderstood. Thanks for clearing that up Mark.
 
Sonny Gill
Ranch Hand
Posts: 1211
Mac IntelliJ IDE
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Gregg Bolinger:
The controller JSP or Servlet passes over the request and session objects to this class, which does any HTTP related processing, and then invokes methods on business logic classes.

How does this class determine what HTTP related processing to perform and what methods to invoke?



My mistake..that was rather ambiguous.

For a particular feature (use-case??), I will usually have one HTTP processing class, and one or more business logic classes.
The business logic classes contain no HTTP related code.
And I try to have no business logic in the controller class, and keep all the common request or session processing there, which is usually predetermined for a particular use-case.

For example for a recent module I am working on, I use the following structure and classes

interface Report
abstract class AbstractReport implements Report

(concrete classes)
Report1 extends AbstractReport implements Report
Report2 implements Report
...and so on..

ReportsController.jsp (delegates all requests for reports to ReportsController.class), and forwards to the JSP returned by that class

ReportsController.class
Does request validation
Create an appropriate Report class based on request parameters
Set some member fields of the Report class based on request parameters using Reflection
call load() method on report
Set the Report object as a request attribute
return the JSP to forward the request to
Do any common exception handling

Report (implementation) classes
Contain all the business logic needed for a particular report

Hmm..infact while we are at it, if anybody can offer suggestions or sees any faults with this structure, any comments would be much appreciated. thanks

Sonny
 
Wait for it ... wait .... wait .... NOW! Pafiffle! A perfect tiny ad!
a bit of art, as a gift, that will fit in a stocking
https://gardener-gift.com
reply
    Bookmark Topic Watch Topic
  • New Topic