I am developing a webapp using Spring MVC 3 and have the DispatcherServlet
catching all requests to \'/\' like so (web.xml):
The URLRewrite is sort of a "hack" if you want to call it that. What it comes down to is, you're re-inventing the wheel; as there are already existing solutions. Another thing to remember is Http Server = Static content & App server = dynamic content (this is how they were designed). By delegating the appropriate responsibilities to each server you maximize efficiency... but now-a-days this is probably only a concern in a performance critical environments and something like Tomcat would most likely work well in both roles most of the time; but it is still something to keep in mind none the less.
For java based spring configuration you can use the following
Using ResourceHandlerRegistry which stores registrations of resource handlers for serving static resources.
More Info @ WebMvcConfigurerAdapter which defines callback methods to customize the Java-based configuration for Spring MVC enabled via @EnableWebMvc.
@EnableWebMvc
@Configurable
@ComponentScan("package.to.scan")
public class WebConfigurer extends WebMvcConfigurerAdapter {
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static_resource_path/*.jpg").addResourceLocations("server_destination_path");
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<mvc:default-servlet-handler/>
</beans>
and if you want to use annotation based configuration use below code
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
I found a way around it using tuckey's urlrewritefilter. Please feel free to give a better answer if you have one!
In web.xml:
<filter>
<filter-name>UrlRewriteFilter</filter-name>
<filter-class>org.tuckey.web.filters.urlrewrite.UrlRewriteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>UrlRewriteFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>app</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>app</servlet-name>
<url-pattern>/app/*</url-pattern>
</servlet-mapping>
In urlrewrite.xml:
<urlrewrite default-match-type="wildcard">
<rule>
<from>/</from>
<to>/app/</to>
</rule>
<rule match-type="regex">
<from>^([^\.]+)$</from>
<to>/app/$1</to>
</rule>
<outbound-rule>
<from>/app/**</from>
<to>/$1</to>
</outbound-rule>
This means that any uri with a '.' in it (like style.css for example) won't be re-written.
I solved it this way:
<servlet-mapping>
<servlet-name>Spring MVC Dispatcher Servlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.jpg</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.gif</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.js</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
This works on Tomcat and ofcourse Jboss. However in the end I decided to use the solution Spring provides (as mentioned by rozky) which is far more portable.
My way of solving this problem is placing all your actions with a specific prefix like "web" or "service" and configure that all url's with that prefix will be intercepted by the DispatcherServlet.