Replacing web.xml with Java based Configuration for Servlet 3.x Webapplications

With the Servlet 3.x API as part of JEE 6 come with the possibility to configure a java web application by writing a java class instead of having a web.xml file inside the WEB-INF folder. My sample apache cxf project has a web.xml with a spring configuration listener and a cxf servlet mapping. I use jetty for integration tests inside maven builds and tomcat as application server for deployment and running the web application. The web service sample use Spring 3.1 and Apache CXF 2.6.2.

I migrated my old web project with just a few steps:

Maven Settings

Step 1: Integrate latest Spring Web API

The Spring 3.1 web project contains the SpringServletContainerInitializer class which will be automatically invoked by a servlet 3.x container:

	
		2.6.2
		3.1.2.RELEASE
	
		
			javax
			javaee-api
			6.0
			provided
		
		
			org.apache.cxf
			cxf-rt-frontend-jaxws
			${cxf.version}
		
		
			org.apache.cxf
			cxf-rt-transports-http
			${cxf.version}
		

		
		
			org.apache.cxf
			cxf-rt-transports-http-jetty
			${cxf.version}
		
		
			org.eclipse.jetty
			jetty-webapp
			8.1.1.v20120215
		
		
			junit
			junit
			4.10
			jar
			compile
		
		
			org.springframework
			spring-test
			${spring.framework.version}
			jar
			compile
		
		
			org.springframework
			spring-core
			${spring.framework.version}
			jar
			compile
		
		
			org.springframework
			spring-beans
			${spring.framework.version}
		
		
			org.springframework
			spring-web
			${spring.framework.version}
		

Step 2: Update build plugin for jetty to use servlet 3.x api

The Jetty 8.x supports Servlet 3.x api to support bootstrapping and java based configurations and is used by the jetty plugin:

			
				org.mortbay.jetty
				jetty-maven-plugin
				8.1.5.v20120716
				
					10
					
						/${project.artifactId}
					
					true
					foo
					9999
					
						
							9090
							60000
						
					
				
				
					
						start-jetty
						pre-integration-test
						
							run
						
						
							0
							true
						
					
					
						stop-jetty
						post-integration-test
						
							stop
						
					
				
			

Step 3: Configure Maven War Plugin to ignore web.xml

The maven war plugin throws otherwise a exception if it does not found the web.xml file:

			
				org.apache.maven.plugins
				maven-war-plugin
				2.2
				
					src/main/webapp
					${project.artifactId}
					false
					
					
						
				
			

 

Java Configuration

Step 4: Write Configuration file

Write a class that implement the WebApplicationInitializer interface from Spring Web and override the onStartup Method. Inside that you have to setup spring application context and map the servlet classes to url patterns:

package demo.spring.cfg;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

import org.apache.cxf.transport.servlet.CXFServlet;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.XmlWebApplicationContext;

public class WebAppInitializer implements WebApplicationInitializer {

	@Override
	public void onStartup(ServletContext container) throws ServletException {
		XmlWebApplicationContext rootContext = new XmlWebApplicationContext();
		rootContext.setConfigLocations(new String[] { "classpath*:applicationContext.xml" });
		container.addListener(new ContextLoaderListener(rootContext));

		ServletRegistration.Dynamic dispatcher = container.addServlet("CXFServlet", CXFServlet.class);
		dispatcher.addMapping("/*");
	}
}

Step 5: Delete web.xml

Delete inside WEB-INF folder the web.xml file and use the mvn clean command to remove it from target folder.

Step 6: Testing

run mvn package to build the war file in your project. Download and extract tomcat 7.x for testing your war file. Put the war file in the webapps folder and run your server with the startup.bat in the bin folder of tomcat.