Thursday, May 31, 2012

Spring WebApplicationInitializer and programmatic support for web.xml file

Servlet 3.0 provides a programmatic way to specify and configure the contents of a web.xml file.

A servlet 3.0 based web application can implement a ServletContainerInitializer interface, which is explicitly passed a ServletContext which is a runtime representation of the container, to be used for configuring the servlets, filters, listeners and other contents normally specified through a typical web.xml file.

If a custom ServletContainerInitializer is provided, the implementation class name has to be declared in a META-INF/services/java.servlet.ServletContainerInitializer file in the classpath.

Spring 3.1+ makes this a process a little easier by providing an implementation of ServletContainerInitializer called the SpringServletContainerInitializer, registers this implementation through the META-INF/services/java.servlet.ServletContainerInitializer file in the spring-web module, and in turn delegates the responsibility of configuring the ServletContext to classes implementing a custom Spring interface called WebApplicationInitializer.

Essentially from a web application developers perspective the only thing that needs to be done is to implement a WebApplicationInitializer, and configure the ServletContext in the implementation. This is how a custom WebApplicationInitializer for a web application looks like for a typical Spring Application:

public class CustomWebAppInitializer implements WebApplicationInitializer {

 public void onStartup(ServletContext container) {
  XmlWebApplicationContext rootContext = new XmlWebApplicationContext();
  rootContext.setConfigLocations(new String[]{"classpath*:META-INF/spring/applicationContext-security.xml", "classpath*:META-INF/spring/applicationContext.xml"});

  container.addListener(new ContextLoaderListener(rootContext));

  ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", DispatcherServlet.class);
  dispatcher.setInitParameter("contextConfigLocation", "/WEB-INF/spring/webmvc-config.xml");

  container.addFilter("Spring OpenEntityManagerInViewFilter",
   .addMappingForUrlPatterns(null, false, "/*");

  container.addFilter("HttpMethodFilter", org.springframework.web.filter.HiddenHttpMethodFilter.class)
   .addMappingForUrlPatterns(null, false, "/*");

  container.addFilter("springSecurityFilterChain", new DelegatingFilterProxy("springSecurityFilterChain"))
     .addMappingForUrlPatterns(null, false, "/*");

  FilterRegistration charEncodingfilterReg = container.addFilter("CharacterEncodingFilter", CharacterEncodingFilter.class);
  charEncodingfilterReg.setInitParameter("encoding", "UTF-8");
  charEncodingfilterReg.setInitParameter("forceEncoding", "true");
  charEncodingfilterReg.addMappingForUrlPatterns(null, false, "/*");

A web.xml is still required though, to configure some things which cannot be completely configured using this mechanism, the stripped down web.xml looks like this:
<?xml version="1.0" encoding="ISO-8859-1" standalone="no"?>
<web-app xmlns="" xmlns:xsi="" 
 version="3.0" xsi:schemaLocation="" metadata-complete="false">

    <display-name>my app</display-name>
    <description>my app</description>


Make a note of the version attribute specified as 3.0, and the schema location being specified as "", these are what trigger the container to consider this as a Servlet 3.0 web application.

That is basically it, with these in place the application can be considered to be configured - mostly without a web.xml file!

Greenhouse application at Github - - look in the servlet3 branch


  1. Thankyou for sharing, helped me iron out a couple of niggles moving from XML to Java config. :)

  2. thanks, helpful post

  3. This is awesome! Thanks for this!

  4. One advantage, I understand, is having a less verbose or stripped down version of web.xml - are there any other advantages of using this programmatic way?