Using <mvc:resources .../> in spring 3 causes all other views to stop working

Simplest example:

I have a dispatcher servlet configured to catch everything:

<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

I have a simple test controller:

@RequestMapping("/index")
@ResponseBody
public String rootTest(){
    return "Main page displayed from TestController";
}

In this test case I am adding (or removing) the following line to dispatcher-servlet.xml:

<mvc:resources mapping="/public/**" location="/public/"/>

My lofty goal: to serve static content (images, css, js) along with my dynamic content (generated via Velocity within a Jetty servlet container, tied together with the almighty Spring).

My Dilema: When I add <mvc:resources .../> I get a 404 for http://localhost/index, but I can serve an image from http://localhost/public/img/42.png. If I remove <mvc:resources .../> then http://localhost/index works fine, but of course, how do I serve static content?

Bonus question: Why can I never have my cake and eat it too?


There are 2 problems:

  1. Never use /* in servlet mapping:

    <servlet-mapping> 
        <servlet-name>dispatcher</servlet-name> 
        <url-pattern>/</url-pattern> 
    </servlet-mapping> 
    
  2. <mvc:resources> requires <mvc:annotation-driven> (or explicitly declared handler mappings, etc).

    This happens because DispatcherServlet applies default configuration of handler mappings only when no custom handler mappings found in the context. Since <mvc:resources> adds its own handler mapping, defaults are broken, therefore other handler mappings should be decalred explicitly, either by <mvc:annotation-driven> or manually as beans.

    Also note that <mvc:resources> declares only DefaultAnnotationHandlerMapping and doesn't declare other mappings such as BeanNameUrlHandlerMapping, though they are in defaults of DispatcherServlet. Declare them manually if you need them.