In this series of articles, I’m going to describe elements of my talk at the TC JUG.

I chose to present the topics in JSR 315 in an ascending order of importance. So let’s begin with what i think is the least important of the lot. I’m sure others will argue with my ordering, but since this is my blog, I get to make the calls ;)

So, let’s begin with annotations.

With JSR 315, the servlet container is finally a completely optional artifact. That’s a bit of oversimplification, but it is certainly true that for the most part. The servlet container must introspect all the classes in WEB-INF/classes as well as in WEB-INF/lib/*.jar looking for annotations. You can speed up servlet container starts by preventing this scanning of classes – if you set the metadata-complete attribute to true on the web-app element of your application’s web.xml.

Let’s begin by taking a look at a filter in the new world.

First, notice that the web.xml file is simply a shadow of its former self – and could have been omitted.

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee

http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"

	version="3.0">
</web-app>

The filter is declared using the @WebFilter annotation and is registered as a filter for the /foo URL pattern.

package com.swengsol.filters;
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.logging.Logger;

/**
 * User: Damodar Chetty
 * Date: Jul 24, 2010
 * Time: 8:39:20 AM
 * An introduction to Servlet 3.0 and Java 6 (TC JUG)
 * (c) Software Engineering Solutions, Inc.
 */

// 1. Annotations can map to either url patterns or servlet names
@WebFilter(urlPatterns = "/foo", filterName = "MyFilter")
public class MyFilter implements Filter {
    private static final Logger logger =
		Logger.getLogger("com.swengsol");
    public void destroy() {
    }

    public void doFilter(ServletRequest req, ServletResponse resp,
		FilterChain chain) throws ServletException, IOException {
        logger.info("> Filtering: " +
			((HttpServletRequest)req).getRequestURI());
        chain.doFilter(req, resp);
    }
    public void init(FilterConfig config) throws ServletException {
        logger.info("> Filter: " + "Initializing filter");
    }
}

The key element to notice here is the annotation that maps the url patterns /foo and /bar to our servlet. The filter we defined earlier will be invoked only when this servlet is requested using the pattern, /foo.

package com.swengsol.servlets;

import com.swengsol.Squawker;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Date;
import java.util.logging.Logger;

/**
* User: Damodar Chetty
* Date: Jul 24, 2010
* Time: 8:26:34 AM
* An introduction to Servlet 3.0 and Java 6 (TC JUG)
* (c) Software Engineering Solutions, Inc.
*/

@WebServlet(name="HelloWorldServlet", urlPatterns={"/foo", "/bar"})
public class HelloWorldServlet extends HttpServlet {
	private static final Logger logger =
		Logger.getLogger("com.swengsol");
	protected void doGet(HttpServletRequest request,
	  HttpServletResponse response)
	  throws ServletException, IOException {
		logger.info("Within request>>>" + getServletName());
		Squawker squawker =
		new Squawker("HelloWorldServlet: annotations map to " +
			"url patterns /foo and /bar: " + new Date());
		response.setContentType("text/html");
		PrintWriter out = response.getWriter();
		out.println(squawker.getHTML());
	}
}

The final annotation of interest is @WebListener, which we demonstrate using a trivial context listener. Registering a different listener is just as simple. You add this annotation to any class that implements a listener interface, and you are in business.

package com.swengsol.listeners;
/**
 * User: Damodar Chetty
 * Date: Jul 23, 2010
 * Time: 10:48:14 PM
 * An introduction to Servlet 3.0 and Java 6 (TC JUG)
 * (c) Software Engineering Solutions, Inc.
 */

import javax.servlet.*;
import javax.servlet.annotation.WebListener;
import java.util.EnumSet;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;

@WebListener
public class MyServletContextListener implements ServletContextListener {
    private static final Logger logger =
			Logger.getLogger("com.swengsol");

    // Public constructor is required by servlet spec
    public MyServletContextListener() {
    }
    public void contextInitialized(ServletContextEvent sce) {
        logger.info("Context Listener > Initialized");
    }
    public void contextDestroyed(ServletContextEvent sce) {
    }
}

So is the web.xml completely redundant? Not quite.

You can still use the web.xml to specify the ordering of components such as filters.

Likewise, you would use it when you wanted to override any configuration settings that may have been specified via annotations.

In just a bit, we’ll look at the programmatic definition of servlets and filters.