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:
Never use /*
in servlet mapping:
<servlet-mapping> <servlet-name>dispatcher</servlet-name> <url-pattern>/</url-pattern> </servlet-mapping>
<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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With