问题
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.
回答1:
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>
回答2:
Did any one consider using this:
<!-- Allows for mapping the DispatcherServlet to "/" by forwarding static resource requests to the container's default Servlet -->
<mvc:default-servlet-handler/>
Here is the latest spring docs on it: http://static.springsource.org/spring/docs/3.1.2.RELEASE/spring-framework-reference/htmlsingle/spring-framework-reference.html#mvc-default-servlet-handler
回答3:
As an alternative to the proposed solution number (2, default servlet which behaves differently from servlet container to servlet container), I would recommend taking a look into the Resource Servlet (org.springframework.js.resource.ResourceServlet
) from the Spring Webflow project.
For more details please have a look at How to handle static content in Spring MVC?
回答4:
I have the same problem but instead of using spring, I do mysefl a small filter that redirect root to my start page like that:
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String pageName = req.getServletPath();
if(pageName.equals("/")) {
res.sendRedirect( req.getContextPath() + "/start" );
} else {
chain.doFilter(request, response);
}
It's maybe a trick but it look like working fine with a small code. Go here for more filter information http://www.oracle.com/technetwork/java/filters-137243.html
来源:https://stackoverflow.com/questions/2129876/using-spring-mapping-to-root-in-web-xml-static-resources-arent-found