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 {
@Override
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");
dispatcher.addMapping("/");
container.addFilter("Spring OpenEntityManagerInViewFilter", org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter.class)
.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="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
version="3.0" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" metadata-complete="false">
<display-name>my app</display-name>
<description>my app</description>
<context-param>
<param-name>defaultHtmlEscape</param-name>
<param-value>true</param-value>
</context-param>
<session-config>
<session-timeout>30</session-timeout>
</session-config>
<error-page>
<exception-type>java.lang.Exception</exception-type>
<location>/uncaughtException</location>
</error-page>
<error-page>
<error-code>404</error-code>
<location>/resourceNotFound</location>
</error-page>
</web-app>
Make a note of the version attribute specified as 3.0, and the schema location being specified as "http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd", 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!
References:
http://blog.springsource.org/2011/06/10/spring-3-1-m2-configuration-enhancements/
Greenhouse application at Github - https://github.com/SpringSource/greenhouse - look in the servlet3 branch
Thanks..helped me a lot
ReplyDeletethanks a lot :)
ReplyDeleteThankyou for sharing, helped me iron out a couple of niggles moving from XML to Java config. :)
ReplyDeletethanks, helpful post
ReplyDeleteThis is awesome! Thanks for this!
ReplyDeleteOne 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?
ReplyDeleteYes, (but the advantage is not for your benefit) you get to lock your company's code base into a third party product instead of using the standard Servlet API
Delete