![[personal profile]](https://www.dreamwidth.org/img/silk/identity/user.png)
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:
A better solution would look something like this:
The traditional servlet template is this:
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.
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.
no subject
Date: 2007-02-27 07:31 pm (UTC)no subject
Date: 2007-02-27 07:48 pm (UTC)no subject
Date: 2007-02-27 09:16 pm (UTC)Пожалуй, фабрика здесь особого смысла не имеет.
Вещи, типа авторизации, полезно выносить в фильтр, чтобы сервлеты про неё вообще не задумывались.