How to convert Spring xml based web application to Java configuration

We needed to convert an internal application from Java based configuration to make design consistent with other applications we have internally. See below for current tech stack and target tech stack and steps we took to achieve it.

Current Tech stack:

  • Servlet 2.5 (with web.xml)
  • Spring 4.0.2 with xml based bean configuration

Target Tech Stack:

  • Servlet 3.0 - Convert web.xml to Java based config
  • Spring 4.0.2 with Java based configuration

Spring has been supporting Servlet 3 Java-based initializer classes for some time now. Simplest approach to convert web.xml to programmatic configuration is by adding a class that implements org.springframework.web.WebApplicationInitializer. This class will be scanned by Spring on application startup and bootstrapped.

AbstractAnnotationConfigDispatcherServletInitializer class take it one step forward. It’s a Base class for WebApplicationInitializer implementations that register a DispatcherServlet configured with annotated classes, e.g. Spring’s @Configuration classes.

Step1 - Convert web.xml to Java based config

Given below is sample web.xml

WEB.XML
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE xml>
<web-app
  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/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
  version="2.5">
	<display-name> Application</display-name>

	<filter>
		<filter-name>characterEncodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>UTF-8</param-value>
		</init-param>
		<init-param>
			<param-name>forceEncoding</param-name>
			<param-value>true</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>characterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	
	<filter>
		<filter-name>customFilter</filter-name>
		<filter-class>com.app.web.config.filter.customFilter</filter-class>
		<init-param>
			<param-name>appName</param-name>
			<param-value>employee</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>customFilter</filter-name>
		<url-pattern>*.do</url-pattern>
	</filter-mapping>

	<servlet>
		<servlet-name>employee</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>employee</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

Corresponding Web application initializer class

WebApplicationInitializer.java
@Order(2)
public class WebApplicationInitializer extends
		AbstractAnnotationConfigDispatcherServletInitializer {

	private static final Logger LOGGER = LoggerFactory.getLogger(WebApplicationInitializer.class);
	
	@Override
	public void onStartup(ServletContext servletContext) throws ServletException {
		
		// Add Custom Filter
		FilterRegistration customFilter = servletContext.addFilter("customFilter", new customFilter());
		customFilter.addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), true, "*.do");
		customFilter.setInitParameter("appName", "employee");
		
		super.onStartup(servletContext);
	}
	
	@Override
	protected Class<?>[] getRootConfigClasses() {
	
		LOGGER.info("Application initialization started." );
		LOGGER.info("WebApplicationInitializer: Configuring Root Config Classes" );	
		return new Class<?>[] {ServiceConfig.class};
	}
	
	@Override
	protected Class<?>[] getServletConfigClasses() {
		LOGGER.info("WebApplicationInitializer: Configuring Spring Web Config Classes" );
		return new Class<?>[] { SpringWebConfig.class};
	}
	
	@Override
	protected String[] getServletMappings() {
		return new String[] { "/" };
	}
	
	@Override
	protected Filter[] getServletFilters() {
		LOGGER.info("WebApplicationInitializer: Configuring Servlet Filters" );
		CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
		characterEncodingFilter.setEncoding("UTF-8");
		
		return new Filter[] { characterEncodingFilter};
	}

}

Step2: Convert Spring xml based configuration to Java based configuration

We can create a class implementing WebMvcConfigurerAdapter class to bootstrap Spring application.

Application-Context.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 	xmlns:context="http://www.springframework.org/schema/context"
 	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 	xmlns:p="http://www.springframework.org/schema/p"
 	xsi:schemaLocation="http://www.springframework.org/schema/beans
    	http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
    	http://www.springframework.org/schema/context
    	http://www.springframework.org/schema/context/spring-context-4.0.xsd
    	http://www.springframework.org/schema/mvc
    	http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
	<context:component-scan base-package="com.app.web.controller" />
		<mvc:annotation-driven />
		
	<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    
   <bean class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping"/>
  	
   	<bean id="viewResolver"
        class="org.springframework.web.servlet.view.UrlBasedViewResolver">
    <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>
    <property name="prefix" value="/WEB-INF/jsp/"/>
    <property name="suffix" value=".jsp"/>
	</bean>
   		
</beans>

Corresponding Spring Web config class

SpringWebConfig.java
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { 
		"com.app.web.controller"
})
public class SpringWebConfig extends WebMvcConfigurerAdapter {

	@Override
	public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
	    configurer.enable();
	}
	
	@Bean
	public InternalResourceViewResolver jspViewResolver() {
	    InternalResourceViewResolver bean = new InternalResourceViewResolver();
	    bean.setViewClass(org.springframework.web.servlet.view.JstlView.class);
	    bean.setPrefix("/WEB-INF/views/");
	    bean.setSuffix(".jsp");
	    return bean;
	}
	
}

That’s All!

Version History


Date Description
2016-01-26    Initial Version