Skip to main content

An Introduction To Servlet 3.0

October 14, 2008

{cs.r.title}







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 ( "http://jcp.org/en/jsr/detail?id=316">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/classes
directory, in a .jar file located in the WEB-INF/lib directory,
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 called
metadata-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 to false, 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 and
javax.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 urlMappings attribute
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 the
HttpMethod annotations like GET,
PUT, POST, HEAD, or
DELETE in the servlet class. These methods should take
the HttpServletRequest and
HttpServletResponse 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 like
HTTPServlet 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.

[prettify]
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>
[/prettify]

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.

[prettify]
@Servlet(urlMappings={"/MyApp"})
public class MyServlet {
    @GET
    public void handleGet(HttpServletRequest req, 
                          HttpServletResponse res) {
                ....
    }
}

Deployment descriptor (web.xml)

optional
[/prettify]

@ServletFilter and @FilterMapping: You can easily create
a servlet filter by annotating the filter class with the
javax.servlet.http.annotation.ServletFilter
annotation. 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 Filter
interface 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:

[prettify]
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>
[/prettify]

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. MyFilter
intercepts all incoming requests whose URL matches the pattern
/foo. Servlet 3.0 makes the deployment descriptor optional
for filter configurations.

[prettify]
@ServletFilter
@FilterMapping("/foo")
public class MyFilter {
  public void doFilter(HttpServletRequest req, 
                       HttpServletResponse res) {
        .....
  }
}

Deployment descriptor (web.xml)

optional
[/prettify]

@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 value english, to a servlet class.

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

@ServletContextListener: The
javax.servlet.http.annotation.ServletContextListener
annotation 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 the
ServletContextListener 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.

[prettify]
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>
[/prettify]

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

[prettify]
@ServletContextListener
public class MyListener {
  public void contextInitialized (ServletContextEvent sce) {

  }
.....
}

Deployment Descriptor (web.xml)

optional
[/prettify]

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 or
modular web.xml. The web fragment is a logical
partitioning of a web application into elements like servlet,
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 , 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 the META-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-complete flag discussed earlier controls the
scanning of web fragments during the startup of the application. A
sample web fragment is shown below:

[prettify]
<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>
[/prettify]

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 to
ServletContext. 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 the
contextInitialized method of
ServletContext. 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:

[prettify]
@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);
    }
}
[/prettify]

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 an
asynchronous, non-blocking fashion (this is the Comet
style 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. The
resume 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 and
ServletResponse 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 the resume,
suspend, and complete 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.

<br "Request handling using asynchronous servlet" />
Figure 1. Request handling using an asynchronous servlet

Security

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. The
login method of HTTPServletRequest will
allow the application or framework to force a container-mediated
authentication. The logout method of
HTTPServletRequest 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 HttpOnly cookies. 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 the Cookie class to support HTTPOnly
cookies:

[prettify]
  void setHttpOnly(boolean isHttpOnly)
  boolean isHttpOnly()
[/prettify]

API changes: The following new convenience methods are
added to ServletRequest to easily get
ServletResponse and ServletContext
instances associated with a request object.

[prettify]
  ServletResponse getServletResponse()
  ServletContext getServletContext()
[/prettify]

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 "https://glassfish.dev.java.net">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 @WebServlet
    and @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 ServletContextListener
    interfaces, respectively.
  • Providing an option for enabling and disabling a Servlet.

See the updated proposal provided in the
Resources 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.

Summary

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.

Resources


width="1" height="1" border="0" alt=" " />
Deepa Sobhana is a Technical Architect currently associated with UST Global, a service based company in Kerala, India.
Related Topics >> Programming   |   Servlets   |