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.

Date: 2007-02-27 07:48 pm (UTC)
From: [identity profile] alf-kadett.livejournal.com
Я что-то вечером непонятлив. Добрая часть жабных сайтов используют один сервлет - ActionServlet (ну ещё по сервлету на JSP, но это отдельная история).

Date: 2007-02-27 09:16 pm (UTC)
From: [identity profile] yakov-sirotkin.livejournal.com
Основная проблема в том, чтобы замапить запросы к сайту на их обработчики. Важно, чтобы была единая точка входа, а не каждый сервлет прописывался отдельно в XML. Вариантов реализации может быть много: конфиг как у struts, reflection и просто длинный список if else, как у тебя внутри
RequestFactory factory(HttpServletRequest) {
    // look at the request, figure out what kind of factory we need, and return it
  }


Пожалуй, фабрика здесь особого смысла не имеет.

Вещи, типа авторизации, полезно выносить в фильтр, чтобы сервлеты про неё вообще не задумывались.

Profile

juan_gandhi: (Default)
Juan-Carlos Gandhi

May 2025

S M T W T F S
    1 2 3
456 7 8 9 10
11 121314151617
181920 21 222324
25262728293031

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated May. 23rd, 2025 03:43 pm
Powered by Dreamwidth Studios