juan_gandhi: (Default)
[personal profile] juan_gandhi
When you, like me, switch from using JSP everywhere to writing servlets that call some rendering widgets, you'll soon discover one simple thing: you'll have to pass around Request and Response. Your servlet works as a small server, not as something that serves one specific request, with the ability to reference, when necessary, session and global data.

What do you do if you want to store and pass around request data? There are two ways: a) add an attribute to the current request, and b) use ThreadLocal - so that your variable looks global, but is attached to the current request.

is it object-oriented? No, it is not. Your servlet code behaves as if it were a "utility function". Pass parameters, output results. Looks a little bit monadic, but not object-oriented.

And why do we need a hundred of various servlets? Just because we store request-specific code right there, in the servlets. Why not subclass a request; figure out the type of the request, use abstract factory to retrieve a specific factory that produces specific request-handling instance, with all the data right inside that instance? Then you would not need so many servlets. You will actually need just one servlet.

Ever saw a server that has just one servlet? Check out industriallogic.com. They have just one servlet. How do I know? I had asked Josh.

Now details.

The traditional servlet template is this:
public void processRequest(HttpServletRequest req, HttpServletResponse res) {
  ....
  if (checkParameters(req)) {
    doTheJob(req, res);
  { else {
    showSomeError(req, res);
  }
}

private boolean checkParameters(req) {
  if (req.getParameter("userid") == null) {
    return false;
  }
  String pwd = req.getParameter("password");

  if (pwd == null || pwd.length() < 5 || pwd.equals("password")) {
    return false;
  } 
  //etc
}


A better solution would look something like this:


The traditional servlet template is this:
public void processRequest(HttpServletRequest req, HttpServletResponse res) {
  FactoryCentral.factory(req).newRequest(req, res).process();
}
...

class FactoryCentral {
...
  RequestFactory factory(HttpServletRequest) {
    // look at the request, figure out what kind of factory we need, and return it
  }

public abstract class RequestFactory {
  abstract AbstractRequest newRequest(HttpServletRequest req, HttpServletResponse res);

public class UserLoginFactory {
  AbstractRequest newRequest(HttpServletRequest req, HttpServletResponse res) {
    return checkParameters(req) ? new UserLoginRequst(req, res) : new BadRequest(req, res, "You are as bad as your request");
  }    
  private boolean checkParameters(req) {
    if (req.getParameter("userid") == null) {
      return false;
    }
    String pwd = req.getParameter("password");

    if (pwd == null || pwd.length() < 5 || pwd.equals("password")) {
      return false;
    }
  } 
  //etc
}


See what I mean? Comments welcome. I also admit that I never mentioned RoR, Hibernate, cgi, .net... not because I hate them, but just because I'm talking about one simple issue - servlets being architecturally wrong.

Date: 2007-02-27 07:31 pm (UTC)
From: [identity profile] gefiltefishka.livejournal.com
the better solution would be using jsf and hibernate.

Profile

juan_gandhi: (Default)
Juan-Carlos Gandhi

June 2025

S M T W T F S
1 234567
891011121314
15161718192021
22232425262728
2930     

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 5th, 2025 02:50 am
Powered by Dreamwidth Studios