The first part of this series described how you can create RESTful urls with Spring MVC 3.1 and default-servlet-handler element of the MVC namespace. This blog entry will describe how you can use the dispatcher servlet url mappings for the same purpose. As you might remember from my previous blog entry, a RESTful url must fulfill these requirements:
- An url address must no have suffix in it (in other words, an url address most not contain a suffix like ‘.action’).
- The context path of the web application must not start with a prefix like ‘app’.
As I mentioned to you before, you can use the dispatcher servlet url mappings for configuring your web application to use RESTful url addresses. This means that you must create section specific context path prefixes and map the dispatcher servlet to these url patterns. This idea might seem a bit confusing at first so I will provide an example which will hopefully explain this idea.
Lets assume that your web page has two sections: products and services. This would mean that you would map your dispatcher servlet to following url patterns: ‘/products/*’ and ‘/services/*’. This approach works rather well if the next part of the context path does not contain a path variable. Lets take a closer look of this in following:
- Following context paths would not work: ‘/products/1′ and ‘/services/5′.
- Following context paths would work: ‘/products/phones/1′ and ‘/services/training/1′.
The reason for this behavior is that the dispatcher servlet removes the url pattern from the beginning of the request’s context path and tries to look for a handler to the request by using the resulting string. (E.g. If you have mapped your dispatcher servlet to url pattern ‘/products/*’ and the context path of the incoming request is ‘/products/phones/1′, the dispatcher servlet is looking for a handler which request mapping matches with the string ‘/phones/1′). This naturally means that context paths like ‘/products/1′ and ‘/services/1′ will not work because the resulting request mapping is not “unique”.
Enough with the theory. The steps needed to create RESTful url addresses by using this technique are described next.
First, you must configure your application context. I have a created a simple Java configuration class which is used to enable Spring MVC, set the component scan base package and configure the view resolver bean. The source code of the configuration class is given in following:
* An application context Java configuration class. The usage of Java configuration
* requires Spring Framework 3.0 or higher.
* @author Petri Kainulainen
*/
@Configuration
@ComponentScan(basePackages = {"net.petrikainulainen.spring.restful.controller"})
@EnableWebMvc
public class ApplicationContext {
private static final String VIEW_RESOLVER_PREFIX = "/WEB-INF/jsp/";
private static final String VIEW_RESOLVER_SUFFIX = ".jsp";
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix(VIEW_RESOLVER_PREFIX);
viewResolver.setSuffix(VIEW_RESOLVER_SUFFIX);
return viewResolver;
}
}
Second, you must configure your web application. In this case the web application configuration consists of two phases:
- Configure the url mapping of the dispatcher servlet.
- Configure the welcome file of your application.
I decided to configure my web application by implementing the WebApplicationInitializer interface. My example adds dispatcher servlet url mappings for the home page, products section and services section of the web application. The source code of my implementation is given in following:
* Web application Java configuration class. The usage of web application
* initializer requires Spring Framework 3.1 and Servlet 3.0.
* @author Petri Kainulainen
*/
public class RestfulInitializer implements WebApplicationInitializer {
private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
private static final String DISPATCHER_SERVLET_MAPPING_HOME = "/home";
private static final String DISPATCHER_SERVLET_MAPPING_PRODUCTS = "/products/*";
private static final String DISPATCHER_SERVLET_MAPPING_SERVICES = "/services/*";
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(ApplicationContext.class);
ServletRegistration.Dynamic dispatcher = servletContext.addServlet(DISPATCHER_SERVLET_NAME, new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping(DISPATCHER_SERVLET_MAPPING_HOME);
dispatcher.addMapping(DISPATCHER_SERVLET_MAPPING_PRODUCTS);
dispatcher.addMapping(DISPATCHER_SERVLET_MAPPING_SERVICES);
servletContext.addListener(new ContextLoaderListener(rootContext));
}
}
Since it is not yet possible to configure the welcome page of a web application by using Java configuration, I had to create a web.xml configuration file and configure the welcome file of my application in it. My web.xml file looks as follows:
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_3_0.xsd"
version="3.0">
<welcome-file-list>
<welcome-file>index.html</welcome-file>
</welcome-file-list>
</web-app>
Third, you must create a index page which redirects user to your home page. In my example, the url mapping of the home page is ‘/home’. I used the Meta Refresh Tag for this purpose. The source code of my welcome file is given in following:
I have now described to you how you can use the dispatcher servlet url mappings for creating RESTful url addresses with Spring MVC. I am having some doubts about this approach for three reasons:
- If new sections are added to your web application, you must always remember to add the correct mapping for the dispatcher servlet. This feels a bit cumbersome.
- The actual url address of your home page is not invisible for the users of your application. I prefer url addresses like http://www.example.com over http://www.example.com/home. This might sound ridiculous but in some situations this is not acceptable.
- The context path of your application must have more than one “level” because otherwise Spring cannot find the correct handler for the requests. This might not a problem in most cases but if it is, you cannot use the approach described in this blog entry.
If you are interested of playing around with my example application, you can get the source code from GitHub. The third and last part of this series will describe how you can create RESTful urls with Spring MVC and UrlrewriteFiter. Stay tuned.


