我有一个Spring MVC 4.2.x
项目。我正在通过基于XML
的配置文件配置它:
<servlet>
<servlet-name>foo</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
在context.xml
文件中,我配置了资源和annotation-driven
模式:
<mvc:resources mapping="/webjars/**" location="/webjars/"/>
<mvc:annotation-driven/>
一切正常,除了一件事:webjars-locator
- Webjars定位器根本不起作用。
我已经开始研究Spring MVC来源以了解出现了什么问题,并发现webjars-locator
通过WebJarsResourceResolver
类工作,该对象在ResourceChainRegistration.getResourceResolvers()
类方法中添加
完整序列如下:
WebMvcConfigurationSupport.resourceHandlerMapping()
&gt;&gt; ResourceHandlerRegistration.getHandlerMapping()
&gt;&gt; ResourceHandlerRegistration.getRequestHandler()
&gt;&gt;
ResourceChainRegistration.getResourceResolvers()
,将其添加为:
if (isWebJarsAssetLocatorPresent) {
result.add(new WebJarsResourceResolver());
}
问题是,如果是上面描述的基于XML的配置,则不会调用此序列,也不会使用WebMvcConfigurationSupport
类。
此外,如果我添加
@EnableWebMvc
@Configuration
public class WebConfig {
}
进入项目,WebMvcConfigurationSupport
显然有效,但在ResourceHandlerRegistration.getHandlerMapping()
:
protected AbstractHandlerMapping getHandlerMapping() {
if (registrations.isEmpty()) {
return null;
}
...
}
registrations
为空!
毕竟,如何强制Spring将WebJarsResourceResolver
添加到解析器链中的唯一方法是:
1)从<mvc:resources mapping="/webjars/**" location="/webjars/"/>
和
context.xml
2)将addResourceHandlers
添加到WebConfig
:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("/webjars/")
.setCachePeriod(3600)
.resourceChain(true) // !!! very important
;
}
我的问题是:我做错了什么?为什么XML基础配置不会导致WebJarsResourceResolver
注册?
答案 0 :(得分:2)
让我们说上下文根路径是/ctx
。使用您的配置,/webjars/RESOURCE
的资源路径实际映射到/ctx/webjars/RESOURCE
;与普遍期望相反,它应该映射到/webjars/RESOURCE
。
基于Spring 4.2.x documentation和an example similar issue,您需要将/webjars/**
映射到默认调度程序servlet:
这允许将DispatcherServlet映射到&#34; /&#34; (从而覆盖容器的默认Servlet的映射),同时仍然允许容器的默认Servlet处理静态资源请求。它配置一个DefaultServletHttpRequestHandler,其URL映射为&#34; / **&#34;和相对于其他URL映射的最低优先级。
这意味着添加以下内容可以解决问题:
<mvc:resources mapping="/webjars/**" location="/webjars/">
<mvc:resource-chain>
<mvc:resource-cache />
</mvc:resource-chain>
</mvc:resources>
<mvc:annotation-driven />
<mvc:default-servlet-handler />
the example petclinic的另一个注释使用location="classpath:/META-INF/resources/webjars/"
用于webjars,我不确定这里是否相关。
希望这有帮助。
由@Andremoniy添加:
对于Spring 4
,它的标记略有不同:
<mvc:resources mapping="/webjars/**" location="/webjars/">
<mvc:resource-chain resource-cache="true"/>
</mvc:resources>