Thursday, 27 May 2010

Servlet 3.0 Annotations

The specification for JSR315: Servlet 3.0 was released in December last year with some interesting new ideas and features. This is still very new and the application servers haven't quite caught up with it yet. At the time of writing, the only server I know of that supports Servlet 3.0 is Glassfish v3. Tomcat 7 will provide support but is apparently not due for release until toward the end of this year.

In this post, I want to take a brief look at the new annotations in Servlet 3.0, and show how, although not ground-breaking, they will reduce the amount of configuration in web.xml.

To run any of these examples, you will need a copy of Glassfish 3.0 or, if you are feeling adventurous, you could try Tomcat 7.0 RC2.

Getting hold of the Servlet 3.0 API

Assuming you are using Maven, you'll need to find yourself a repository artifact that corresponds to the new specification. The central repository now has the required artifacts, so no need to mess around adding repositories:

pom.xml
<dependency>
    <groupId>javax</groupId>
    <artifactId>javaee-api</artifactId>
    <version>6.0</version>
</dependency>

Note you may also find an artifact called javaee-web-api. As far as I can tell from a cursory glance, this contains the same classes as javaee-api.

Servlet with Annotations

Servlet 3.0 provides the @WebServlet annotation to define a servlet, obviating the need for configuration in web.xml.

SampleServlet.java
package blogger;

import java.io.IOException;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@WebServlet(value="/sampleServlet", loadOnStartup=1)
public class SampleServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response)
    throws ServletException, IOException {
        response.setContentType("text/plain");
        response.getWriter().write(new Date().toString());
    }

}

Simply create the class, deploy the project and invoke the servlet using the path specified in the annotation, e.g. http://localhost:8080/<contextPath>/sampleServlet. Note that things like load on startup can be specified for servlets using the annotation.

Listener with Annotations

Listeners can be defined in much the same way. Again, no configuration is required in web.xml.

SampleListener.java
package blogger;

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@WebListener
public class SampleListener implements HttpSessionListener {

    private static final Logger log = LoggerFactory.getLogger(SampleListener.class);

    @Override
    public void sessionCreated(HttpSessionEvent arg0) {
        log.info("Session created");
    }

    @Override
    public void sessionDestroyed(HttpSessionEvent arg0) {
        log.info("Session destroyed");
    }

}

I've used SLF4J for logging here, which is becoming more popular as a logging framework wrapper, used by Spring 3.0 for example. To make this work, you'll need to add the following to your pom.xml. Note there's no need to add an artifact for Log4J.

pom.xml
...

<properties>
    <slf4j.version>1.5.8</slf4j.version>
</properties>

...

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>${slf4j.version}</version>
</dependency>
<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-log4j12</artifactId>
    <version>${slf4j.version}</version>
</dependency>

To configure the underlying Log4J, you'll need something like this copied out to your classpath:

log4j.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC "-//LOGGER" "log4j.dtd">

<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <param name="target" value="system.out"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%-5p %d{ABSOLUTE} %c{1} - %m%n"/>
        </layout>
    </appender>

    <root>
        <priority value="info"/>
        <appender-ref ref="console" />
    </root>

</log4j:configuration>

Filter with Annotations

Same idea again here. No configuration in web.xml.

SampleFilter
package blogger;

import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@WebFilter("/sampleServlet")
public class SampleFilter implements Filter {

    Logger log = LoggerFactory.getLogger(SampleFilter.class);

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
    throws IOException, ServletException {
        chain.doFilter(request, response);
        if (response instanceof HttpServletResponse) {
            log.info("Applying cache control filter to response");
            HttpServletResponse httpServletResponse = (HttpServletResponse)response;
            httpServletResponse.setHeader("Cache-Control", "nocache");
        }
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {}

    @Override
    public void destroy() {}

}

In this case, the parameter in the @WebFilter annotation specifies the paths to which the filter is applied. In my case, just to the sample servlet above.

One of the limitations of the annotations for filters is that there is no way of specifying the ordering. If multiple filters were in use, and the ordering was important, you'd have to revert to a schema-based configuration in web.xml.

Web Deployment Descriptor

None of the above examples need a web.xml file. By default, the welcome file list includes index.html and index.jsp. If you need to configure things like session timeouts, prelude/coda, etc., you will need a web.xml file. This is an example of a basic Servlet 3.0 version:

web.xml
<?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">
    <session-config>
        <session-timeout>15</session-timeout>
    </session-config>
</web-app>

Settings in web.xml, by the way, can also be used to override the settings provided by the annotations. The web.xml takes precedence. You can also set metadata-complete to true in web.xml to tell the container only to consider configuration in web.xml and skip annotations altogether.

Conclusion

So, there you have it. Servlet 3.0 annotations. As I said in the introduction, they aren't ground-breaking in terms of setting up your application, but they do make it slightly easier to configure servlets, filters and listeners in your web applications. I suspect 99% of the time, we will still need a web.xml file, but it could be less cluttered.

13 comments:

maheshv said...

The Servlet 3.0 could have supported annotations for simple POJO. I am not sure why we still have to extend the HttpServlet?

class SampleListener implements HttpSessionListener

Richard Senior said...

I wrote the post based on the "final" Servlet 3.0 specification linked at the top of the post. This shows the @WebServlet annotation with classes extending HttpServlet, etc. and does not describe the @Servlet and @GET annotations that I have seen in other places that would allow use of a POJO.

rolojavadeveloper said...

I have been try to startup a webservlet with annotation and doesn´t work. I work with tomcat 6. I make a class with @WebServlet annotation with the same parameters, deploy and start the server, and put url with the servlet name and get the http 404 error.

Regards

Richard Senior said...

Check back at the first paragraph rolo: you need Tomcat 7 or Glassfish 3 to use anything from the Servlet 3.0 spec.
Tomcat 7 is now released but I've not tried it, only Glassfish 3.

Gopi Krishna said...

AngularJS is a toolset for building the framework most suited to your application development. It is fully extensible and works well with other libraries. Every feature can be modified or replaced to suit your unique development workflow and feature needs. Read on to find out how.

AngularJS Training in Chennai
AngularJS Training Institute in Chennai

AngularJS Certification Training in Chennai

Harish said...

Thank you for sharing this useful information.

Angularjs Training in Chennai | Angularjs Training institute in Chennai

gowsalya said...

Thanks a lot very much for the high quality and results-oriented help. I won’t think twice to endorse your blog post to anybody who wants and needs support about this area.
digital marketing training in tambaram

digital marketing training in annanagar

digital marketing training in marathahalli

digital marketing training in rajajinagar

Digital Marketing online training

full stack developer training in pune

Ananya Krishnan said...

Good job in presenting the correct content with the clear explanation. The content looks real with valid information. Good Work

DevOps is currently a popular model currently organizations all over the world moving towards to it. Your post gave a clear idea about knowing the DevOps model and its importance.

Good to learn about DevOps at this time.


devops training in chennai | devops training in chennai with placement | devops training in chennai omr | devops training in velachery | devops training in chennai tambaram | devops institutes in chennai | devops certification in chennai | trending technologies list 2018

Robotic Process Automation Tutorial said...

Really useful information. Thank you so much for sharing.It will help everyone.Keep Post. RPA training in chennai | RPA Uipath training in chennai | RPA training in Chennai with placement

Aman CSE said...


Such a wonderful blog on Machine learning . Your blog have almost full information about Machine learning .Your content covered full topics of Machine learning that it cover from basic to higher level content of Machine learning . Requesting you to please keep updating the data about Machine learning in upcoming time if there is some addition.
Thanks and Regards,
Machine learning tuition in chennai
Machine learning workshops in chennai
Machine learning training with certification in chennai

Roja Priya said...

Thank you for sharing your article. Great efforts put it to find the list of articles which is very useful to know, Definitely will share the same to other forums.

best openstack training in chennai | openstack course fees in chennai | openstack certification in chennai | openstack training in chennai velachery

Aman CSE said...

Appericated the efforts you put in the content of Data Science .The Content provided by you for Data Science is up to date and its explained in very detailed for Data Science like even beginers can able to catch.Requesting you to please keep updating the content on regular basis so the peoples who follwing this content for Data Science can easily gets the updated data.
Thanks and regards,
Data Science training in Chennai
Data Science course in chennai with placement
Data Science certification in chennai
Data Science course in Omr

IT Tutorials said...

Really useful information. Thank you so much for sharing.It will help everyone.Keep Post. RPA training in chennai | RPA training in Chennai with placement | UiPath training in Chennai | UiPath Chennai

Followers