使用Spring,在web.xml中映射到root,找不到静态资源

时间:2010-01-25 02:25:23

标签: model-view-controller spring tiles

我要做的是将请求映射到servlet根目录(正确的术语?)。我正处于将URL映射到正确视图的位置,但无法找到属于页面一部分的所有静态内容--css,javascript,images。

所以在我的web.xml中,我的servlet标签看起来像这样

<servlet-mapping>
    <servlet-name>springapp</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

我的控制器看起来像这样:

@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非常简单。它看起来像这样:

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);
}

我在视图层中使用了Tiles。我的配置如下:

    

           /WEB-INF/tiles-defs.xml         

正如我所提到的,找到了视图,但无法找到作为页面端口的静态资源。这是一些典型的退出:

  

2010-01-24 17:25:01,777 DEBUG [http-8080-7] servlet.DispatcherServlet   (DispatcherServlet.java:690) - 名为“springapp”的DispatcherServlet   处理[/springapp/static/css/account.css]的GET请求   2010-01-24 17:25:01,778 WARN [http-8080-4] servlet.DispatcherServlet   (DispatcherServlet.java:962) - 找不到HTTP请求的映射   带有名称的DispatcherServlet中的URI [/springapp/static/css/shop.css]   'springapp'2010-01-24 17:25:01,778 DEBUG [http-8080-6]   servlet.FrameworkServlet(FrameworkServlet.java:677) - 成功   完成请求2010-01-24 17:25:01,778警告[http-8080-5]   servlet.DispatcherServlet(DispatcherServlet.java:962) - 没有映射   找到带有URI的HTTP请求[/springapp/static/css/offers.css]   DispatcherServlet,名称为“springapp”2010-01-24 17:25:01,778 WARN   [http-8080-3] servlet.DispatcherServlet(DispatcherServlet.java:962) -   没有找到带有URI的HTTP请求的映射   DispatcherServlet中的[/springapp/static/css/scrollable-buttons.css]   名字叫'springapp'

http://localhost:8080/springapp/shop工作正常,但缺少css和图像。

我认为使用Tiles在某种程度上使事情变得复杂但我不愿意摆脱它。我想知道我是否需要调整我的视图分辨率配置需要以某种方式调整?链接视图解析器可能吗?我是只是没有经历过那样做。

4 个答案:

答案 0 :(得分:61)

问题是对静态内容的请求转到dispatcherServlet,因为它被映射为<url-pattern>/</url-pattern>。在具有“RESTful”URL的应用程序中(即DispatcherServlet映射中没有任何前缀),这是一个非常常见的问题。

有几种方法可以解决这个问题:


从Spring 3.x开始,访问静态资源的首选方法是使用<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/" /> 

另见MVC Simplifications in Spring 3


<强> 1。使用网址重写过滤器
请参阅mvc-basic示例here

<强> 2。为default servlet设置前缀:

<servlet-mapping>
    <servlet-name>default</servlet-name>
    <url-pattern>/static/*</url-pattern>
</servlet-mapping>

也就是说,/static/images/image.png的请求将返回名为/images/image.png的文件 但是,这种方式在不同的servlet容器之间是不兼容的(在Jetty中不起作用),请参阅变通方法here

第3。为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。请勿使用RESTful URL,请使用前缀为

的网址
<servlet-mapping> 
    <servlet-name>springapp</servlet-name> 
    <url-pattern>/app</url-pattern> 
</servlet-mapping>

<强> 5。请勿使用RESTful网址,请使用带扩展名的网址

<servlet-mapping> 
    <servlet-name>springapp</servlet-name> 
    <url-pattern>*.do</url-pattern> 
</servlet-mapping>

答案 1 :(得分:5)

有没有人考虑过这个:

<!-- Allows for mapping the DispatcherServlet to "/" by forwarding static resource requests to the container's default Servlet -->
<mvc:default-servlet-handler/>

以下是最新的春季文档: http://static.springsource.org/spring/docs/3.1.2.RELEASE/spring-framework-reference/htmlsingle/spring-framework-reference.html#mvc-default-servlet-handler

答案 2 :(得分:4)

作为建议的解决方案编号的替代方法(2,默认servlet,其行为与servlet容器不同,与servlet容器不同),我建议您查看资源Servlet org.springframework.js.resource.ResourceServlet )来自Spring Webflow项目。

有关详细信息,请查看How to handle static content in Spring MVC?

答案 3 :(得分:1)

我有同样的问题,但我没有使用spring,而是使用mysefl一个小的过滤器,将root重定向到我的起始页面:

    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);
    }

这可能是一个技巧但它看起来像一个小代码工作正常。 点击此处了解更多过滤信息http://www.oracle.com/technetwork/java/filters-137243.html