What I'm trying to do is map requests to the servlet root (correct terminology?). I'm at the point where URLs are mapped to correct view but all the static content - css, javascript, images - that is part of the page cannot be found.
So in my web.xml my servlet tag looks like this
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
My controller looks something like this:
@RequestMapping("/shop")
public class TheShopController extends MyBaseController {
public static String VIEW = "Tile.Shop";
@Override
@RequestMapping(method = RequestMethod.GET)
protected ModelAndView processRequest(HttpServletRequest req, HttpServletResponse resp) {
ModelAndView mav = new ModelAndView(VIEW);
return mav;
}
}
MyBaseController is very simple. It looks like this:
public abstract class MyBaseController extends AbstractController {
protected Logger log = Logger.getLogger(getClass());
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest req, HttpServletResponse resp)
throws Exception {
ModelAndView mav = processRequest(req, resp);
return mav;
}
protected abstract ModelAndView processRequest(HttpServletRequest req, HttpServletResponse resp);
}
I'm using Tiles in my view layer. My configuration is as follows:
/WEB-INF/tiles-defs.xml
As I mentioned, the views are found but the static resources that are a port of the page can't be found. Here is some typical logging out put:
2010-01-24 17:25:01,777 DEBUG [http-8080-7] servlet.DispatcherServlet (DispatcherServlet.java:690) - DispatcherServlet with name 'springapp' processing GET request for [/springapp/static/css/account.css] 2010-01-24 17:25:01,778 WARN [http-8080-4] servlet.DispatcherServlet (DispatcherServlet.java:962) - No mapping found for HTTP request with URI [/springapp/static/css/shop.css] in DispatcherServlet with name 'springapp' 2010-01-24 17:25:01,778 DEBUG [http-8080-6] servlet.FrameworkServlet (FrameworkServlet.java:677) - Successfully completed request 2010-01-24 17:25:01,778 WARN [http-8080-5] servlet.DispatcherServlet (DispatcherServlet.java:962) - No mapping found for HTTP request with URI [/springapp/static/css/offers.css] in DispatcherServlet with name 'springapp' 2010-01-24 17:25:01,778 WARN [http-8080-3] servlet.DispatcherServlet (DispatcherServlet.java:962) - No mapping found for HTTP request with URI [/springapp/static/css/scrollable-buttons.css] in DispatcherServlet with name 'springapp'
Going to http://localhost:8080/springapp/shop works fine but the css and images are missing.
I think that using Tiles is somehow complicating things but I"m reluctant to get rid of it. I'm wondering if I need to adjust my view resolution configuration needs to be tweeked somehow? Chaining view resolvers maybe? I'm just not that experienced in doing that.
The problem is that requests for the static content go to the dispatcherServlet, because it's mapped as <url-pattern>/</url-pattern>
. It's a very common problem in applications with "RESTful" URLs (that is, without any prefix in the DispatcherServlet
mapping).
There are several possible ways to solve this problem:
Since Spring 3.x the preferred way to access static resources is to use <mvc:resources>
:
web.xml
:
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
Spring config:
<!-- Handles GET requests for /resources/** by efficiently serving static content
in the ${webappRoot}/resources dir -->
<mvc:resources mapping="/resources/**" location="/resources/" />
See also MVC Simplifications in Spring 3
1. Use URL rewrite filter
See mvc-basic
example here
2. Set a prefix for the default
servlet:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/static/*</url-pattern>
</servlet-mapping>
That is, request for /static/images/image.png
will return the file named /images/image.png
However, this way is incompatible across different servlet containers (doesn't work in Jetty), see workarounds here
3. Set static content extensions for the default
servlet:
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>*.png</url-pattern>
<url-pattern>*.js</url-pattern>
<url-pattern>*.css</url-pattern>
</servlet-mapping>
4. Do not use RESTful URLs, use URLs with prefix:
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>/app</url-pattern>
</servlet-mapping>
5. Do not use RESTful URLs, use URLs with extension:
<servlet-mapping>
<servlet-name>springapp</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>