Making web development a bit more simple

When someone starts to make a path, most people tend to follow the trail. So when Sun introduced the Servlet API, most people were uneasy about the design problems:

  • Servlets are singletons (which are evil; this is due to performance problems in Java 1.2 which have been fixed about ten years ago).
  • The resulting code smells (feature envy since you call many methods of HttpServletRequest/Response, long method since you can’t call subdivide the doGet() without passing at least two parameters to each new method, duplicated code since you have to walk instance trees to get at a lot of information, …)

Whenever I see Java servlet code, I always wonder why people don’t solve this. It’s so simple:

public abstract class ServletRequestHandler {
    protected HttpServlet servlet;
    protected HttpServletRequest request;
    protected HttpServletResponse response;
    protected String contentType = "text/html";

    public void init(
        HttpServlet servlet, 
        HttpServletRequest request, 
        HttpServletResponse response
    ) {
        this.servlet = servlet;
        this.request = request;
        this.response = response;
    }

    public abstract void process();

    public PrintWriter out() {
        if( null == out ) {
            response.setContentType( contentType );
            
            try {
                out = response.getWriter();
            } catch( IOException e ) {
                throw new RuntimeException( 
                    "Can't get writer", e 
                );
            }
        }
        return out;
    }
    
    public ServletRequestHandler html( String html ) {
        out().print( html );
        return this;
    }
    
    public ServletRequestHandler attribute( String value ) {
        out().print( escape( value ) );
        return this;
    }
    
    public ServletRequestHandler attribute(
        String name,
        String value
    ) {
        if( StringUtils.isBlank( value ) ) {
            return this;
        }
        
        PrintWriter out = out();
        out.print( ' ' );
        out.print( name );
        out.print( "=\"" );
        out.print( escape( value ) );
        out.print( "\"" );
        return this;
    }
    
    public ServletRequestHandler text( String value ) {
        out().print( escape( value ) );
        return this;
    }
    
    // Add more methods to support your favorite
    // web design patterns
}

Now, all your servlets look the same: They accept the request, create a new instance of the right implementation of ServletRequestHandler, and call init() plus process(). With a bit of glue code, you can even use Spring to manage all your servlets for you. No more dabbling with web.xml!

And the best part: This pattern allows you to test the servlet code from a unit test without any container. Just use Spring or Mockrunner to get mock-ups for the J2EE API classes.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: