Webjars 定位器不适用于基于 XML 的 Spring MVC 4.2.x 配置?
Webjars-locator doesn't work with XML based Spring MVC 4.2.x configuration?
我有一个 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
class 工作,对象是在 ResourceChainRegistration.getResourceResolvers()
class 方法中添加。
完整序列如下所示:
WebMvcConfigurationSupport.resourceHandlerMapping()
>> ResourceHandlerRegistration.getHandlerMapping()
>> ResourceHandlerRegistration.getRequestHandler()
>>
ResourceChainRegistration.getResourceResolvers()
,其中添加为:
if (isWebJarsAssetLocatorPresent) {
result.add(new WebJarsResourceResolver());
}
问题是,在上述基于 XML 的配置的情况下,不会调用此序列,也不会使用 WebMvcConfigurationSupport
class。
此外,如果我添加
@EnableWebMvc
@Configuration
public class WebConfig {
}
进入项目,WebMvcConfigurationSupport
显然有效,但在 ResourceHandlerRegistration.getHandlerMapping()
:
protected AbstractHandlerMapping getHandlerMapping() {
if (registrations.isEmpty()) {
return null;
}
...
}
registrations
为空!
毕竟,如何强制使Spring将WebJarsResourceResolver
添加到解析器链中的唯一方法是:
1) 从 context.xml
和
中删除 <mvc:resources mapping="/webjars/**" location="/webjars/"/>
2) 将addResourceHandlers
添加到WebConfig
:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("/webjars/")
.setCachePeriod(3600)
.resourceChain(true) // !!! very important
;
}
我的问题是:我做错了什么?为什么 XML 基础配置不会导致 WebJarsResourceResolver
被注册?
假设上下文根路径是/ctx
。根据您的配置,/webjars/RESOURCE
的资源路径 实际上 映射到 /ctx/webjars/RESOURCE
;与应该映射到 /webjars/RESOURCE
的普遍期望相反。
基于 Spring 4.2.x documentation and an example similar issue,您需要将 /webjars/**
映射到默认调度程序 servlet 为:
This allows for mapping the DispatcherServlet to "/" (thus overriding the mapping of the container’s default Servlet), while still allowing static resource requests to be handled by the container’s default Servlet. It configures a DefaultServletHttpRequestHandler with a URL mapping of "/**" and the lowest priority relative to other URL mappings.
这意味着添加以下内容应该可以解决问题:
<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>
回答您剩下的问题:
它 is/was 2016 年 5 月 3 日报告的一个问题:
https://github.com/webjars/webjars/issues/1395
如本页所述,此问题还提到 Spring MVC 需要 resourceChain() 方法。我今天创建了一个 PR 来解决这个问题:
https://github.com/webjars/webjars/pull/1946
仅供参考:我试图让版本不可知 url 按照文档中描述的方式工作,但没有成功。在此过程中,我还发现了以下问题,其中提到“必须为与版本无关的 WebJars 调用 resourceChain() 方法”:
https://github.com/spring-projects/spring-framework/issues/25410
我有一个 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
class 工作,对象是在 ResourceChainRegistration.getResourceResolvers()
class 方法中添加。
完整序列如下所示:
WebMvcConfigurationSupport.resourceHandlerMapping()
>> ResourceHandlerRegistration.getHandlerMapping()
>> ResourceHandlerRegistration.getRequestHandler()
>>
ResourceChainRegistration.getResourceResolvers()
,其中添加为:
if (isWebJarsAssetLocatorPresent) {
result.add(new WebJarsResourceResolver());
}
问题是,在上述基于 XML 的配置的情况下,不会调用此序列,也不会使用 WebMvcConfigurationSupport
class。
此外,如果我添加
@EnableWebMvc
@Configuration
public class WebConfig {
}
进入项目,WebMvcConfigurationSupport
显然有效,但在 ResourceHandlerRegistration.getHandlerMapping()
:
protected AbstractHandlerMapping getHandlerMapping() {
if (registrations.isEmpty()) {
return null;
}
...
}
registrations
为空!
毕竟,如何强制使Spring将WebJarsResourceResolver
添加到解析器链中的唯一方法是:
1) 从 context.xml
和
<mvc:resources mapping="/webjars/**" location="/webjars/"/>
2) 将addResourceHandlers
添加到WebConfig
:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("/webjars/")
.setCachePeriod(3600)
.resourceChain(true) // !!! very important
;
}
我的问题是:我做错了什么?为什么 XML 基础配置不会导致 WebJarsResourceResolver
被注册?
假设上下文根路径是/ctx
。根据您的配置,/webjars/RESOURCE
的资源路径 实际上 映射到 /ctx/webjars/RESOURCE
;与应该映射到 /webjars/RESOURCE
的普遍期望相反。
基于 Spring 4.2.x documentation and an example similar issue,您需要将 /webjars/**
映射到默认调度程序 servlet 为:
This allows for mapping the DispatcherServlet to "/" (thus overriding the mapping of the container’s default Servlet), while still allowing static resource requests to be handled by the container’s default Servlet. It configures a DefaultServletHttpRequestHandler with a URL mapping of "/**" and the lowest priority relative to other URL mappings.
这意味着添加以下内容应该可以解决问题:
<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>
回答您剩下的问题
它 is/was 2016 年 5 月 3 日报告的一个问题:
https://github.com/webjars/webjars/issues/1395
如本页所述,此问题还提到 Spring MVC 需要 resourceChain() 方法。我今天创建了一个 PR 来解决这个问题:
https://github.com/webjars/webjars/pull/1946
仅供参考:我试图让版本不可知 url 按照文档中描述的方式工作,但没有成功。在此过程中,我还发现了以下问题,其中提到“必须为与版本无关的 WebJars 调用 resourceChain() 方法”:
https://github.com/spring-projects/spring-framework/issues/25410