This blog entry describes how you can create RESTful url addresses to your web application with Spring MVC 3.1 and UrlRewriteFilter. In other words, the url addresses of your application must fulfill following requirements:
- An url address must have a suffix in it (in other words, an url address most not contain a suffix like ‘.action’).
- The context path of the web application which is visible to the users of the application must not start with a prefix like ‘app’.
Next I am going to describe the steps which are needed to fulfill these requirements with Spring MVC 3.1 and UrlRewriteFilter.
The first step is to configure the dispatcher servlet and UrlRewriteFilter. This step consist of two phases:
- Map the dispatcher servlet to url pattern ‘/app/*’ and the UrlRewriteFilter to url pattern ‘/*’.
- Configure the UrlRewriteFilter to hide the url pattern of dispatcher servlet.
First, you have to configure you web application. If you are using Spring 3.1 and Servlet 3.0, you can do this by implementing the WebApplicationInitializer interface. Otherwise you will have to create a web.xml configuration file which contains the same configuration (This is left as an exercise for the reader). The source code of my web application configuration class is given in following:
private static final String DISPATCHER_SERVLET_NAME = "dispatcher";
private static final String DISPATCHER_SERVLET_MAPPING = "/app/*";
private static final String URL_REWRITE_FILTER_NAME = "urlRewrite";
private static final String URL_REWRITE_FILTER_MAPPING = "/*";
private static final String URL_REWRITE_FILTER_PARAM_LOGLEVEL = "logLevel";
private static final String URL_REWRITE_FILTER_LOGLEVEL_SLF4J = "slf4j";
@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);
servletContext.addListener(new ContextLoaderListener(rootContext));
FilterRegistration.Dynamic urlReWrite = servletContext.addFilter(URL_REWRITE_FILTER_NAME, new UrlRewriteFilter());
urlReWrite.setInitParameter(URL_REWRITE_FILTER_PARAM_LOGLEVEL, URL_REWRITE_FILTER_LOGLEVEL_SLF4J);
EnumSet<DispatcherType> urlReWriteDispatcherTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.FORWARD);
urlReWrite.addMappingForUrlPatterns(urlReWriteDispatcherTypes, true, URL_REWRITE_FILTER_MAPPING);
}
}
Second, you must configure the UrlRewriteFilter properly. The web application root of my example application has following directory structure:
- Static resources such as css files are located under static folder.
- JSP files are located under WEB-INF/jsp folder.
The UrlRewriteFilter can be configured by creating a configuration file called urlrewrite.xml to WEB-INF folder. The contents of this file is given in following:
<!-- All requests to root are forwarded to home page. -->
<rule>
<from>/</from>
<to last="true">/app/home</to>
</rule>
<!-- Ensures that requests are forwarded to dispatcher servlet. -->
<rule match-type="regexp">
<!--
Processes only requests which are not:
1) Requests made for obtaining static resources.
2) Already in a correct format.
3) Requests made for obtaining the view.
-->
<condition type="request-uri" operator="notequal">^/(static|app|WEB-INF)/.*</condition>
<from>^/(.*)</from>
<to last="true">/app/$1</to>
</rule>
<!--
Removes the /app/ prefix from href of links. NOTE:
This only works if you use the jstl url tag or spring url tag.
-->
<outbound-rule>
<from>/app/**</from>
<to>/$1</to>
</outbound-rule>
</urlrewrite>
The second step is to implement your web application. You must follow these two principles during the implementation phase:
- Add the correct request mappings to controller classes. Remember that you must not add the ‘/app/’ prefix to the value attribute of your @RequestMapping annotation.
- Use the url tag of JSTL or Spring tab library in the JSP pages (or simply leave the ‘/app/’ prefix out from the href attribute of the html link tag).
I will use the source code of my example application to provide an example which should clarify the principles given above. The class called HomeController is responsible of processing the requests made to the home page of my example application. The source code of this class is given in following:
The home view is called home.jsp and its source code is given in following:
<%@ taglib prefix="c" uri="http://java.sun.com/jstl/core" %>
<html>
<head>
<title>Spring MVC Restful Url Example Application - Home</title>
<link rel="stylesheet" type="text/css" href="/static/css/styles.css"/>
</head>
<body>
<h1>Home</h1>
<p>
<!--
When the page is rendered to browser, this links points to '/page'.
The request made to that url is processed by the PageController class.
-->
<c:url value="/app/page" var="pageUrl"/>
<a href="${pageUrl}">Move to an another page</a>.
</p>
</body>
</html>
I have now described to you how can create RESTful urls with Spring MVC 3.1 And UrlRewriteFilter. This approach feels a bit hacky but I am using it in one of my projects because I have not been able to solve the problem with the default servlet name and Jetty 8.1.0.RC0. Also, if you want to implement RESTful urls by using older Spring MVC versions, this is your best option (It should be fairly easy to create the needed configuration files based on this example).
PS. You can get the soure code of my example application from Github.
Related Posts
- Creating RESTful Urls with Spring MVC 3.1 Part Two: Dispatcher Servlet Url Mappings
- Creating RESTful Urls with Spring MVC 3.1 Part One: default-servlet-handler
- Implementing a Custom Naming Strategy With Hibernate
- Testing that All Service Methods Are Annotated with @Transactional Annotation
- Creating Profile Specific Configuration Files With Maven


