Search This Blog

Wednesday 20 January 2016

Servlet 3.x - Building the web.xml less Web Application

Ever since Java introduced  annotations, every framework has been looking to provide an XML alternative to their configuration information. So how could servlets be left behind.
So I decided to build a servlet application using annotations. In fact I decided to be a little more ambitious. Build a servlet web app without the deployment descriptor.
I created a servlet, a filter and a listener:
@WebFilter(description = "testFilter", displayName = "testFilter", filterName="SampleFilter", 
 urlPatterns = { "*.do", "/htm/" }, 
 initParams = @WebInitParam(name = "param1", value = "val1"),      
dispatcherTypes = { DispatcherType.FORWARD, DispatcherType.REQUEST}

)
public class TestFilter implements Filter {
 
 @Override
 public void init(FilterConfig filterConfig) throws ServletException {
  System.out.println("TestFilter initialized as " + filterConfig.getFilterName() 
                                + " with init parameter value "
    + filterConfig.getInitParameter("param1"));
 }

  @Override
  public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, 
      FilterChain filterChain) throws IOException, ServletException {
    System.out.println("request received in TestFilter");
    filterChain.doFilter(servletRequest, servletResponse);
    return;
  }

  @Override
  public void destroy() {
    System.out.println("LocalFilter destroyed");
  }
}
You still need to extend the Filter interface.
The filter properties that we specified in web.xml can be replaced by using the WebFilter annotation. The WebInitParam annotation allows us to define init parameters for the filter.
Next is the Servlet:
@SuppressWarnings("serial")
@WebServlet(displayName = "TestServlet", description = "Test Servlet", 
  loadOnStartup = 1, urlPatterns = {"*.do" },
  //same as value
  initParams = { 
        @WebInitParam(name = "param1", value = "val1"),
        @WebInitParam(name = "param2", value = "val2") }
)
public class TestServlet extends HttpServlet {

  @Override
  public void init(ServletConfig servletConfig) throws ServletException {
    super.init(servletConfig);
    System.out.println("TestServlet initialized as " + servletConfig.getServletName()
        + " with init parameter values " + servletConfig.getInitParameter("param1") + " and "
        + servletConfig.getInitParameter("param2"));
  }

  @Override
  protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException {
    resp.getOutputStream()
           .write("<html><body>Request received</body></html>".getBytes());
  }
}
Just like the Filter, the Servlet attributes can also be defined using annotations.
Last is the Listener:
@WebListener(value = "This is used to monitor Servlet Lifecycle events")
public class TestListener implements ServletContextListener {
  public void contextInitialized(ServletContextEvent event) {
    System.out
        .println("ServletContext " + event.getServletContext().getServletContextName()
            + " has been initialized  at " + new Date());
  }

  public void contextDestroyed(ServletContextEvent event) {
    System.out
        .println("ServletContext " + event.getServletContext().getServletContextName()
            + " has been destroyed  at " + new Date());
  }
}
The Listener annotation simply identifies the class as a listener. Based on the class hierarchy, the Listener type is identified. We can register the below Listener types:
  • Context Listener
  • Context Attribute Listener 
  • Servlet Request Listener 
  • Servlet Request Attribute Listener 
  • Http Session Listener 
  • Http Session Attribute Listener 
Another interesting annotation I found is the HandlesTypes annotation which I will cover in a later post. There are also annotations for Servlet security (covered in this link).
However there are certain things that cannot be achieved using annotations:
  1. Defining the welcome pages
  2. Defining the error page
  3. Providing display name, description for the web application.
  4. Defining context parameters
  5. Session Configuration Information - e.g. default session timeout
  6. Configurations for jsp files.
  7. Mime mappings ( wonder if they are used anymore)
I went over the list and I think these are OK to be configuring from XML files. They do not seem to be anything, I need to control through the code. Although the rate at which annotations are spreading, don't be surprised if you found annotations for a few of these in upcoming servlet specs. 

No comments:

Post a Comment