【发布时间】:2015-01-08 12:19:39
【问题描述】:
配置
Tomcat 7.0.47 上的 Servlet 3.0
春季 3.1
问题
我有一个特殊的情况,我需要两个DispatcherServlets:一个处理资源请求,一个处理普通的@RequestMapping-type 请求。出于某种原因,我在日志中得到了这个:
在名称为“resources”的 DispatcherServlet 中找不到具有 URI [/my-app/images/someimage.png] 的 HTTP 请求的映射
这是我的web.xml 文件的样子:
<servlet>
<servlet-name>resources</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>resources</servlet-name>
<url-pattern>/css/*</url-pattern>
<url-pattern>/images/*</url-pattern>
<url-pattern>/js/*</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
在resources-servlet.xml 我有这个:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd"
default-autowire="byName">
<context:annotation-config />
<context:property-placeholder />
<mvc:resources mapping="/images/**" location="/images/"/>
<mvc:resources mapping="/js/**" location="/js/"/>
<context:component-scan base-package="lesscss" />
<mvc:annotation-driven />
</beans>
如您所见,我没有用于 CSS 文件的 <mvc:resources>,因为该映射是通过 @Controller 即时构建 LESS 文件完成的。 <context:component-scan base-package="lesscss" /> 负责处理这一点,它似乎正在工作。
我以前在我的springmvc-servlet.xml 文件中有那些<mvc:resources> 标签,但我删除了它们。我还能错过什么?
更新
我尝试将我的web.xml 文件更改为使用*.ext url-patterns 而不是/dir/* 类型,并且成功了。不过,我宁愿不必列出所有扩展,所以我仍然希望有更好的解决方案来解决这个问题。
更新
我将<mvc:resources mapping="/images/**" location="/images/"/> 更改为<mvc:resources mapping="/**" location="/images/"/> 并删除了js 文件的那个,图像开始工作。在 Spring 中映射事物时,* 之前的 servlet-mapping url-pattern 似乎被忽略了。有没有办法解决这个问题?
解释为什么我“需要”两个 Servlet
我想我会添加这个只是为了帮助以前没有意识到这一点的其他人(比如我),并让某人有机会提出更好的解决方案(如果有的话)。
使用<mvc:resources> 标记时,创建的处理程序是常规DispatcherServlet 请求处理的一部分。这意味着,如果您没有明确说明所有 不 由 <mvc:resources> 使用 <mvc:mapping> 处理的资源路径(我仍在使用 Spring 3.1 并且不能使用 <mvc:exclude-mapping>),每个对图像、JavaScript 文件和样式表的请求会运行您在 <mvc:interceptors> 中列出的所有 HandlerInterceptors。我的应用程序中有很多拦截器,由于应用程序的结构和性质,列出所有路径非常容易出错。不仅仅是性能下降,所有这些HandlerInterceptors 的执行实际上会破坏手写的POST-redirect-GET 组件。
另一种方法是检查每个 HandlerInterceptor 方法中正在使用哪个处理程序,但这几乎不是 DRY,也容易出错,如果不扩展它们,我无法对 OpenSessionInViewInterceptor 等类进行此调整。我想出的避免所有这些混乱的解决方案是使用一个单独的 servlet 专门用于静态(ish)资源。
【问题讨论】:
-
你为什么坚持把它分成两个
DispatcherServlets? -
顺便说一句。要解决您的问题,只需将您的 servlet 映射到
/resources路径。 -
解释需要两个
DispatcherServlets 的时间太长了;只知道它必须是那样的。此外,/resources不能在此处使用,因为资源位于应用根目录中。 -
它们在哪里都没有关系......映射中使用的路径将在Spring查找资源时被剥离。您只需在 HTML / JSP 中将它们称为
/resources/js/foo.js。 -
有太多的位置需要改变。我的 HTML 中的路径是
/my-app/css/foo.css等。
标签: spring spring-mvc tomcat servlets