An Introduction To Servlet 3.0 Blog


    Java servlets, a widely accepted technology for building dynamic content for web-based applications, has witnessed major empowerment in its features and Application Program Interface (API) with the release of an early draft version of the Servlet 3.0 specification. This Java Specification Request (JSR) has been approved in the form of JSR 315 and is planned to be part of Java Enterprise Edition 6 (JSR 316) or higher. Unlike some previous releases of the specification, which were just maintenance releases, the Servlet 3.0 specification is packed with lots of exciting features required for the new era of web development. In this article, we will investigate key features introduced in the new version of Java servlets. It is worthwhile to note that the specification is still in a draft stage and therefore the technical details discussed in this article are subject to change.

    The new specification focuses on delivering the following new features:

    • Ease of development
    • Pluggability and extensibility
    • Asynchronous support
    • Security enhancements
    • Other miscellaneous changes

    It is quite evident that servlets have enjoyed much wider use than any other technology in the Java Enterprise Edition family. The beauty of servlets remains in their simplicity and ability to process HTTP requests and pass the response back to web clients. Servlets can be used for implementing business logic of simple and small applications. In the case of web frameworks, servlets serve as an entry point (a controller servlet) for all incoming requests; consequently, all popular frameworks are built on top of raw servlets. The new features in Servlet 3.0 are aimed at easing the development of servlet applications and will benefit both servlet developers and framework developers. In the following sections, let us look into each of these features in detail and see how we can utilize them for developing better applications.

    Ease of Development

    Ease of development is one of the key success mantras of any technology. The Servlet 3.0 API focuses on ease of development by making use of JSR 175 annotations to enable declarative-style programming. This means that you can swiftly develop a servlet or a filter class by simply annotating the class with appropriate annotations like @Servlet or@ServletFilter. Annotations not only make the coding of servlet, filter, and listener classes easier, but also make deployment descriptors optional for a web application, even though the application archive may have servlet, filter, or context listener classes. The web container is responsible for processing the annotations located in classes in the WEB-INF/classesdirectory, in a .jar file located in the WEB-INF/libdirectory, or in classes found elsewhere in the application's classpath.

    Annotations Vs. Deployment Descriptor

    It is interesting to note that the deployment descriptor takes precedence over annotations. In other words, the deployment descriptor overrides configuration information specified through the annotation mechanism. Version 3.0 of the web deployment descriptor contains a new attribute calledmetadata-complete on the web-app element. This attribute defines whether the web descriptor is complete, or whether the class files of the web application should be examined for annotations that specify deployment information. If the attribute is set to true, the deployment tool must ignore any servlet annotations present in the class files and use only the configuration details mentioned in the descriptor. Otherwise, if the value is not specified or set tofalse, the container must scan all class files of the application for annotations. This provides a way to enable or disable scanning of the annotation and its processing during the startup of the application.

    All annotations introduced in Servlet 3.0 can be found under the packages javax.servlet.http.annotation andjavax.servlet.http.annotation.jaxrs. The following section explains the complete set of annotations in Servlet 3.0 :

    @Servlet:javax.servlet.http.annotation.Servlet is a class-level annotation that affirms the annotated class as a servlet and holds metadata about the declared servlet. The urlMappingsattribute is a mandatory attribute of @Servlet that specifies the URL pattern that invokes this servlet. When a request arrives, the container matches the URL in the request with the servlet's urlMappings and if the URL pattern matches, the corresponding servlet will be invoked to serve the request. All other attributes of this annotation are optional, with reasonable defaults. There must be a method annotated with any one of theHttpMethod annotations like GET,PUT, POST, HEAD, orDELETE in the servlet class. These methods should take the HttpServletRequest andHttpServletResponse as method parameters. Version 3.0 servlets can be implemented as Plain Old Java Objects (POJOs) as opposed to previous versions; i.e., servlets no longer have to extend any of the basic servlet implementation classes likeHTTPServlet or GenericServlet.

    For comparison, a code snippet for writing a Java servlet using the old Servlet 2.5 API is shown below. In Servlet 2.5, the web container will initialize the servlet only if you configure the details of the servlet in the deployment descriptor.

    public class MyServlet extends HttpServlet { public void doGet (HttpServletRequest req, HttpServletResponse res) { .... } } 
    Deployment descriptor (web.xml) <web-app> <servlet> <servlet-name>MyServlet</servlet-name> <servlet-class>samples.MyServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>MyServlet</servlet-name> <url-pattern>/MyApp</url-pattern> </servlet-mapping> ... </web-app> 

    Here is the much simplified version written to the Servlet 3.0 API. As MyServlet is annotated as a servlet using the@Servlet annotation, it gets initialized during the startup of the web container. Note that the deployment descriptor is optional in this case.

    @Servlet(urlMappings={"/MyApp"}) public class MyServlet { @GET public void handleGet(HttpServletRequest req, HttpServletResponse res) { .... } } 
    Deployment descriptor (web.xml) 

    @ServletFilter and@FilterMapping: You can easily create a servlet filter by annotating the filter class with thejavax.servlet.http.annotation.ServletFilterannotation. This annotation encloses metadata about the filter being declared. It is also mandatory to have the@FilterMapping annotation on the filter class. The@FilterMapping annotation defines the URL pattern for the filter. All other attributes of @ServletFilter are optional, with reasonable defaults. The v3.0 filter classes will now look as POJO classes and there will be no Filterinterface or no-argument public constructor required for these classes. Given below is the code snippet of a filter class using the Servlet v2.5 API:

    public class MyFilter implements Filter { public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { ...... } } 
    Deployment descriptor (web.xml) <web-app> <filter> <filter-name>My Filter</filter-name> <filter-class>samples.MyFilter</filter-class> </filter> <filter-mapping> <filter-name>My Filter</filter-name> <url-pattern>/foo</url-pattern> </filter-mapping> ... </web-app> 

    A sample filter class written using Servlet 3.0 is shown below. The container marks MyFilter as a filter class, as it is annotated with ServletFilter. MyFilterintercepts all incoming requests whose URL matches the pattern/foo. Servlet 3.0 makes the deployment descriptor optional for filter configurations.

    @ServletFilter @FilterMapping("/foo") public class MyFilter { public void doFilter(HttpServletRequest req, HttpServletResponse res) { ..... } } 
    Deployment descriptor (web.xml) 

    @InitParam: This annotation can be used to define any initialization parameters that must be passed to the servlet or filter classes. It is an attribute of the@Servlet and @ServletFilter annotation. The following code sample explains how to pass an initialization parameter named lang, having the valueenglish, to a servlet class.

    @Servlet(urlMappings={"/MyApp"}, initParams ={@InitParam(name="lang", value="english")}) public class MyServlet { @GET public void handleGet(HttpServletRequest req, HttpServletResponse res) { .... } } 

    @ServletContextListener: Thejavax.servlet.http.annotation.ServletContextListenerannotation declares the class as a servlet context listener. The context listener receives notifications when the web container creates or destroys the ServletContext. The context listener will be a POJO class, and does not have to implement theServletContextListener interface. A listener class written using the Servlet 2.5 API is shown below. The container will recognize the listener class if and only if you configure its details in deployment descriptor.

    public class MyListener implements ServletContextListener { public void contextInitialized(ServletContextEvent sce) { } ..... } 
    Deployment Descriptor (web.xml) <web-app> <listener> <listener-class>samples.MyListener</listener-class> </listener> .... </web-app> 

    A much simplified listener class using the Servlet 3.0 API is shown below.

    @ServletContextListener public class MyListener { public void contextInitialized (ServletContextEvent sce) { } ..... } 
    Deployment Descriptor (web.xml) 

    Pluggability and Extensibility

    Nowadays, web frameworks such as Struts, JSF, and Spring are becoming widely accepted and established techniques for building web applications. Integrating these frameworks into a web application is not so easy, as it involves assimilating different pieces together and then editing a single descriptor file that describes how all of these pieces fit together. Most of these frameworks mandate that you configure the details of the framework like servlet classes (typically a Controller Servlet), filter classes, or listener classes in your application's deployment descriptor file. The main reason for this configuration requisite is that today's web applications support only a single monolithic deployment descriptor wherein we define all deployment information. When the size of the application increases, the dependency on external frameworks may also increase, resulting in complex deployment descriptor files. As you probably know, maintenance of complex descriptors is always a hassle.

    In order to resolve these issues, one of Servlet 3.0's most significant concepts is the idea of web fragments ormodular web.xml. The web fragment is a logical partitioning of a web application into elements likeservlet, servlet-mapping,servlet-filter, filter-mapping,servlet-listener, and their child elements. The framework developers can leverage this feature to define their own web fragments that reside within the framework, and developers can plug in more and more frameworks by just including the library files in the application's classpath, without modifying the existing deployment descriptor. In short, this feature is aimed at having zero configuration when working with frameworks or libraries.

    The deployment descriptor has been changed to include a new element called <web-fragment>, which holds the details of a web fragment. If the fragment is packaged as a .jar file and has metadata information in the form of a deployment descriptor, then the web.xml file must be included under theMETA-INF directory of the .jar file. At deployment time, the container scans the application's classpath and discovers all web fragments and processes them. The metadata-completeflag discussed earlier controls the scanning of web fragments during the startup of the application. A sample web fragment is shown below:

    <web-fragment> <servlet> <servlet-name>myservlet</servlet-name> <servlet-class>samples.MyServlet</servlet-class> </servlet> <listener> <listener-class>samples.MyListener</listener-class> </listener> </web-fragment> 

    To provide enhanced pluggability, Servlet 3.0 provides much-needed support for the programmatic addition of servlets and filter classes with the help of new APIs added toServletContext. These new APIs allows you to declare servlets, filter classes, and their URL mappings programmatically. These classes get initialized during application startup time or runtime. Most importantly, you can call these APIs only from thecontextInitialized method ofServletContext. Refer to the Servlet 3.0 API docs for more details of these APIs. A code sample for programmatically adding a servlet and a filter class is shown below:

    @ServletContextListener public class MyListener { public void contextInitialized (ServletContextEvent sce) { ServletContext sc = sce.getServletContext(); //Declare servlet and servlet mapping sc.addServlet("myServlet", "Sample servlet", "samples.MyServlet", null, -1); sc.addServletMapping("myServlet", new String[] {"/urlpattern/*"}); //Declare filter and filter mapping sc.addFilter("myFilter", "Sample Filter", " samples.MyFilter", null); sc.addFilterMapping("myFilter", new String[] {"/urlpattern/*"}, "myServlet", DispatcherType.REQUEST, false); } } 

    Asynchronous Support

    All of us have probably had deal with slow-serving servlets, particularly servlets that have to wait for a response from a web service, a JDBC connection, a JMS message, and so on. In the current scenario, the servlet has to wait for all long-running processes to complete before generating the response, resulting in inefficient blocking operations that consume a thread or other limited resources of the container. Another adverse effect is that in case of a JDBC connection, for example, the database may have many blocking threads waiting for access. This kind of a scenario will ultimately lead to thread starvation and poor quality of service for the entire web container.

    In order to overcome the above-mentioned shortcomings, Servlet 3.0 adds support for suspending and resuming request processing, which enables the servlet to service a request in anasynchronous, non-blocking fashion (this is the Cometstyle of programming). When a request is suspended, the thread handling the request will return to the container without generating any response and gets ready to perform other tasks. Theresume method on the request resumes the request processing. Whenever the requested resource becomes available, the thread handling that event resumes the suspended request and proceeds to generate the response. Listed below are some of the capabilities of asynchronous servlets:

    • The ability to receive data from a client without blocking even if the data is slow arriving (non-blocking input).
    • The ability to send data to a client without blocking, even if the client or network is slow (non-blocking output).
    • The ability to handle delayed requests. Delayed request handling is useful if a remote/slow resource must be obtained before servicing the request or if access to a specific resource needs to be throttled to prevent too many simultaneous accesses.
    • The ability to handle delayed response close; i.e., the response will be held open to allow additional data to be sent when asynchronous events occur.
    • The ability to notify blocking or non-blocking events.

    A set of new APIs are added to ServletRequest andServletResponse for suspending, resuming, and querying for the status of the request and enabling disabling and querying the status of the response. The notification events for theresume, suspend, andcomplete methods of request are available for developers through the requestSuspended(), requestResumed() and requestCompleted()methods, respectively. Refer to the Servlet 3.0 API for detailed information about these methods. The sequence of events involved in fetching data from a remote web service using asynchronous servlets is illustrated in Figure 1.

    Request handling using asynchronous servlet
    Figure 1. Request handling using an asynchronous servlet


    This topic is not included in the early draft of the 3.0 specification, as it is still undergoing discussions within the expert group. However, the proposal recommends providing the ability to log in and log out programmatically. New APIs will be added to HTTPServletRequest to enable this. Thelogin method of HTTPServletRequest will allow the application or framework to force a container-mediated authentication. The logout method ofHTTPServletRequest and HTTPSession allows an application to reset the authentication state of the request.

    Other Miscellaneous Changes

    Listed below are some of the enhancements made to the existing APIs for easy data retrieval and better developer experience.

    HttpOnly Cookies: The Servlet 3.0 specification allows cookies to be marked as HttpOnlycookies. HttpOnly cookies are not exposed to client-side scripting code, thereby preventing certain kinds of cross-site scripting attacks. Most modern browsers support this feature. Listed below are the methods added to theCookie class to support HTTPOnlycookies:

    void setHttpOnly(boolean isHttpOnly) boolean isHttpOnly() 

    API changes: The following new convenience methods are added to ServletRequest to easily getServletResponse and ServletContextinstances associated with a request object.

    ServletResponse getServletResponse() ServletContext getServletContext() 

    The Roadmap

    The early draft review of the 3.0 specification was completed in June 2008. As Servlet 3.0 is targeted for the Java EE 6 platform and higher, the proposed final release of the specification is also aligned with the release of Java EE 6. However, the early bits of the specification will be made available through GlassFish, which is the reference implementation for Java EE. The reference implementation of Servlet 3.0 is expected to be integrated into version 3 of GlassFish.

    There are changes happening around the review draft of JSR, and new proposals are coming into the picture to address suggestions and feedback from the community. The key changes in the new proposal are listed below:

    • @Servlet is renamed to @WebServletand @ServletContextListener to@WebServletContextListener
    • .
    • The new proposal suggests that @WebServlet must extend the HTTPServlet class. Therefore, servlet classes might not be POJO classes, as described earlier.
    • Similarly, the @ServletFilter class and@WebServletContextListener classes need to implement the Filter and ServletContextListenerinterfaces, respectively.
    • Providing an option for enabling and disabling a Servlet.

    See the updated proposal provided in theResources section of this article for more details. Also note that these new features are subject to change, depending upon the final approval of this proposal.


    In this article, we have discussed the exciting features proposed in the early draft specification of Servlet 3.0. The specification has already started receiving vivid response from the community. Ease of development through annotation mechanisms, zero configurations for using frameworks and libraries, asynchronous servlets, pluggability, security, and more are the much-awaited features of Java Servlets. That said, some who've read the specification are expressing concern about the possible overuse of annotations, security threats in scanning web fragments, etc. But, as discussed earlier, most of these concerns are handled in the new proposal. However, there is no doubt that Java Servlet 3.0 will ease the lives of servlet developers and provide better support for developing next-generation web application.