Introduction
This tip discusses an alternative way of programmatic approach to configure web.xml entries.
Background
As a traditional approach, any servlet context and other listeners are configured by making entries in the web.xml file in any Java/J2EE web based application. In contrast to this, the introduction of servlet 3.0 aims to provide a programmatic approach to configure the entries of web.xml.
Using Programmatic Approach
Any servlet 3.0 based web application can just implement a ServletContainerInitializer
interface, which the ServletContext
interface will be explicitly passed at runtime and acts as a representation of the container. This can be used to configure servlet, listeners, any filters and other contents which was normally specified in the typical web.xml file.
With advanced spring framework 3.1 and above, this implementation has been made much easier. Because it provides an implementation of ServletContainerInitializer
known as the SpringServletContainerInitializer
. Basically, it registers the implementation through the META-INF/services/java.servlet.ServletContainerInitializer file in the spring web module file. Also, the task of configuring the servlet context, listeners, and filters will be delegated to another interface of spring called WebApplicationInitializer
.
The only task for the developer is to implement the WebApplicationInitializer
and configure the servlet context in the implementation.
Let us see a sample on how to implement the same:
The typical web.xml for a servlet configuration will be as shown below:
<servlet>
<servlet-name>dispatcher-servlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher-servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Now, the above entry can be configured programmatically as shown below:
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
public void onStartup(ServletContext container) {
XmlWebApplicationContext appContext = new XmlWebApplicationContext();
appContext.setConfigLocation("/WEB-INF/spring/dispatcher-servlet.xml");
servletContext.addListener(new ContextLoaderListener(context));
ServletRegistration.Dynamic dispatcher = container.addServlet
("dispatcher", new DispatcherServlet(appContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
Initializer
In the above Java code snippet, the interface WebApplicationInitializer
has been used. This is the base of the implementation for configuring web.xml entries using a programmatic approach. Let us look deeper into the above code and know what is happening with the same.
- The above class is implementing the
WebApplicationInitializer
interface. - The method
onStartup
is overridden in order to configure/add ServletContext
and DispatcherServlet
. XmlWebApplicationContext
has been initialized and the configuration file is read from the location of the dispatcher-servlet.xml file. ContestLoaderListener
is added to the ServletContext
. This will integrate the XMLWebApplicationContext
to the life cycle of the ServletContext
. - Dispatcher servlet is created and initialized to
XMLWebApplicationContext
and URL mappings is added (*/).
Configuration Classes
Now, we will create one main app config class called AppConfiguration.java, which does nothing much except inform the spring framework to read the components.
public class MyWebAppInitializer implements WebApplicationInitializer {
@Configuration
@ComponentScan(basePackages = "com.web.configure.example")
public class AppConfiguration {
}
Conclusion
The above programmatic approach of configuring the web.xml entry is always verbose and very easy. It is also easy to debug when any issues occur in the configuration made as well.