Monday, 25 January 2016

Replacing web.xml with Java based configuration for Servlet 3.x Webapplications using Spring

Background



As we know if you want to deploy a web app in a container like tomcat you have a context file called web.xml that creates context necessary for you app to run. For eg. you can provide libraries that will be available to your web app. 

Your typical web.xml will look like - 


<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">

  <display-name>Spring Web MVC Demo Application</display-name>

  <servlet>
      <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
  </servlet>

  <servlet-mapping>
     <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
  </servlet-mapping>
   

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/root-context.xml</param-value>
    </context-param>

    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
</web-app>


Lets see its Java equivalent

Java Configuration

  • For Java configuration you can write your own class that implements WebApplicationInitializer  interface and override it's
    onStartup() method.
  • WebApplicationInitializer is an interface provided by Spring MVC that ensures your implementation is detected and automatically used to initialize any Servlet 3 container.
  • An abstract base class implementation of WebApplicationInitializer named AbstractDispatcherServletInitializer makes it even easier to register the DispatcherServlet by simply overriding methods to specify the servlet mapping and the location of the DispatcherServlet configuration.  
  • This is from Spring 3.1+
Lets now see the Java config -


public class MyWebApplicationInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) {
    
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();

        rootContext.register(RootApplicationConfig.class);
       
        container.addListener(new ContextLoaderListener(rootContext));
       
        AnnotationConfigWebApplicationContext displacherContext = new AnnotationConfigWebApplicationContext();
        displacherContext.register(MyWebConfig.class);
    
    
        ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet(displacherContext));
        registration.setLoadOnStartup(1);
        registration.addMapping("/");
    }
} 


Or as I mentioned before you can extend abstract class AbstractDispatcherServletInitializer.

public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {

    @Override
    protected WebApplicationContext createRootApplicationContext() {
        return null;
    }

    @Override
    protected WebApplicationContext createServletApplicationContext() {
        XmlWebApplicationContext cxt = new XmlWebApplicationContext();
        cxt.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
        return cxt;
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }


Now you don't need web.xml as part of your web application. Your container will startup your app using Java config provided. This classes are detected automatically.

If you are not using Spring you will need to do -

  1. Create a custom class that implements ServletContainerInitializer (i.e. com.osfg.MyServletContainer
  2. Create a file in your META-INF/services folder named javax.servlet.ServletContainerInitializer which will contain the name of your implementation above (com.osfg.MyServletContainer)
In Spring ofcourse you don't need to do this.

Related Links

t> UA-39527780-1 back to top