How to access static resources when mapping a global front controller servlet on /*

Rahul Garg picture Rahul Garg · May 15, 2009 · Viewed 114.3k times · Source

I've mapped the Spring MVC dispatcher as a global front controller servlet on /*.

<servlet>       
  <servlet-name>home</servlet-name>         
  <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>     
</servlet>  
<servlet-mapping>       
  <servlet-name>home</servlet-name>         
  <url-pattern>/*</url-pattern>     
</servlet-mapping>

However, this mapping stops the access to static files like CSS, JS, images etc which are all in the /res/ folder.

How can I access them anyway?

Answer

BalusC picture BalusC · Aug 29, 2010

Map the controller servlet on a more specific url-pattern like /pages/*, put the static content in a specific folder like /static and create a Filter listening on /* which transparently continues the chain for any static content and dispatches requests to the controller servlet for other content.

In a nutshell:

<filter>
    <filter-name>filter</filter-name>
    <filter-class>com.example.Filter</filter-class>
</filter>
<filter-mapping>
    <filter-name>filter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

<servlet>
    <servlet-name>controller</servlet-name>
    <servlet-class>com.example.Controller</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>controller</servlet-name>
    <url-pattern>/pages/*</url-pattern>
</servlet-mapping>

with the following in filter's doFilter():

HttpServletRequest req = (HttpServletRequest) request;
String path = req.getRequestURI().substring(req.getContextPath().length());

if (path.startsWith("/static")) {
    chain.doFilter(request, response); // Goes to default servlet.
} else {
    request.getRequestDispatcher("/pages" + path).forward(request, response);
}

No, this does not end up with /pages in browser address bar. It's fully transparent. You can if necessary make "/static" and/or "/pages" an init-param of the filter.