views:

34

answers:

1

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?

+1  A: 

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.

axtavt
Thanks very much! Question though (I'm new with spring), I had (in an attempt to follow the docs) added <context:component-scan base-package="com.mydomain.web"/> to scan the controllers, does mvc:annotation-driven replace that? I'm a little fuzzy between the "easy new way to do things" vs. "doing things the old way", seems that there is 3 ways to do everything in Spring and sometimes I think I mix them.
David Parks
@David: `<mvc:annotation-driven>` doesn't replace `<context:component-scan>`, it just configures new features of Spring MVC (perhaps it's poorly named).
axtavt