Migrating to Servlets 3.0: Thoughts on @WebServlet


Recently I migrated FileIt.in code to Servlets 3.0 specification. This migration helped in reducing the size of my web.xml as I was able to put all the url-path-patterns of the servlets in the @WebServlet annotation itself.

Contents


Do I still have web.xml?

Yes, I do. I have the following details mentioned in my web.xml:

  1. My custom welcome-file-list.
  2. Error page configuration.
  3. JSP files mapped to different path (XPath: /web-app/servlet/jsp-file).

@WebServlet

A sample code from FileIt.in:

import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
...

@WebServlet(name="ServletAddPost", urlPatterns="/add/post")
public class ServletAddPost extends HttpServlet {
 ...
}

So @WebServlet has considerably reduced the complexity of managing servlet details in web.xml.

Wondering about the design decisions of @WebServlet

Some doubts cropped in my mind when I was converting my existing code:

Doubt 1: Why two attributes having the same functionality?

The Servlet 3.0 spec mandates that one of value or urlPatterns attribute must be specified for @WebServlet annotation. Both are array types, and both have the same functionality: specify the url-pattern of the servlet. Why this introduced complexity?

From the Servlet 3.0 specification::

The urlPatterns or the value attribute on the annotation MUST be present. It is recommended to use value when the only attribute on the annotation is the url pattern and to use the urlPatterns attribute when the other attributes are also used. It is illegal to have both value and urlPatterns attribute used together on the same annotation.

As you see, it gives guidance when to use what. But I do not get the rationale.

Doubt 2: Why is it mandatory to have value or urlPatterns attribute?

The urlPatterns or the value attribute on the annotation MUST be present.

Why?

In my older code I had few servlets without any URL mapping. I used to programatically call these servlets thus (from another servlet):

getServletContext()
  .getNamedDispatcher("MyServletName")
  .forward(req, res);

So why is this not possible in Servlets 3.0? Why do I have to map dummy URLs to servlets that are never going to be called from that URL?

So, doesn't Servlet 3.0 spec support url-pattern-less servlets?

It does support. When you programatically create the servlets. Yes, now you can call the following method in the ServletContext instance:

// Called in the init() method of a servlet...
getServletContext()
  .addServlet("ServletViewPosts", ServletViewPosts.class);

Conclusion

The Servlet 3.0 migration has been interesting for me as a learning exercise, and reduction in complexity of managing web.xml. But it also made me write some additional code for managing url-pattern-less servlets.

Note

I have been testing my Servlets 3.0 code in Caucho Resin 4.0.6.

Posted on Fri Apr 16 13:29:27 EDT 2010 by Subhash Chandran
servlet javaee