【问题标题】:Using Spring, mapping to root in web.xml, static resources aren't found使用Spring,映射到web.xml中的root,找不到静态资源
【发布时间】:2011-01-08 22:46:15
【问题描述】:

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

所以在我的 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 调试 [http-8080-7] servlet.DispatcherServlet (DispatcherServlet.java:690) - 名称为“springapp”的 DispatcherServlet 处理 [/springapp/static/css/account.css] 的 GET 请求 2010-01-24 17:25:01,778 警告 [http-8080-4] servlet.DispatcherServlet (DispatcherServlet.java:962) - 没有为 HTTP 请求找到映射 DispatcherServlet 中带有名称的 URI [/springapp/static/css/shop.css] 'springapp' 2010-01-24 17:25:01,778 调试 [http-8080-6] servlet.FrameworkServlet (FrameworkServlet.java:677) - 成功 完成请求 2010-01-24 17:25:01,778 WARN [http-8080-5] servlet.DispatcherServlet (DispatcherServlet.java:962) - 无映射 找到带有 URI [/springapp/static/css/offers.css] 的 HTTP 请求 名称为“springapp”的 DispatcherServlet 2010-01-24 17:25:01,778 警告 [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 会使事情变得复杂,但我不愿意摆脱它。我想知道我是否需要调整我的视图分辨率配置需要以某种方式调整?链接视图解析器可能吗?我是只是没有那么有经验。

【问题讨论】:

    标签: model-view-controller spring tiles


    【解决方案1】:

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

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


    从 Spring 3.x 开始,访问静态资源的首选方式是使用 &lt;mvc:resources&gt;: web.xml:

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

    弹簧配置:

    <!-- 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.使用 URL 重写过滤器
    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 中不起作用),请参阅 workarounds 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,使用带前缀的 URL:

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

    5.不要使用 RESTful URL,使用带有扩展名的 URL:

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

    【讨论】:

    • 我真正想做的是使用@RequestMapping注解和@PathVariable注解来实现RESTful url的使用。最终,所有静态资源都将由 apache 提供,但这将在生产环境中。我需要在本地运行时由 tomcat 提供的静态资源,例如在开发中。以前用过urlrewrite过滤器,很喜欢,不过想找个别的办法。
    • 我使用了 org.tukey.urlrewrite 过滤器和上面的 #4 的组合。谢谢!
    • 你摇滚。仅供参考,我尝试了#2,它在我的本地环境中工作,该环境在 tomcat 的根网站下运行。一旦我将它部署到测试服务器,在一个名为“test”的非根站点下,它就停止了工作。出于某种原因, /static/ 之前的 /test/ 正在抛弃默认的 servlet 映射。刚刚切换到#3,它就像一个魅力。我已经为此苦苦挣扎太久了。谢谢! +1
    • @axtavt :我在访问 REST 时遇到了类似的问题,不确定是不是因为映射错误。你能帮我看看吗:stackoverflow.com/questions/25285805/… 谢谢!
    【解决方案2】:

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

    更多详情请关注How to handle static content in Spring MVC?

    【讨论】:

      【解决方案3】:

      我有同样的问题,但我没有使用 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

      【讨论】:

        【解决方案4】:

        有没有人考虑过使用这个:

        <!-- 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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2014-04-13
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-07-21
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多