[英]Webjars-locator doesn't work with XML based Spring MVC 4.2.x configuration?
I have a Spring MVC 4.2.x
project.我有一个
Spring MVC 4.2.x
项目。 I am configuring it via XML
based configuration file:我通过基于
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>
In the context.xml
file I have configured resources and annotation-driven
mode:在
context.xml
文件中我配置了资源和annotation-driven
模式:
<mvc:resources mapping="/webjars/**" location="/webjars/"/>
<mvc:annotation-driven/>
Everything works fine except the one thing: webjars-locator
- Webjars locator doesn't work at all .一切正常,除了一件事:
webjars-locator
- Webjars locator 根本不起作用。
I've started look into the Spring MVC sources to understand what's going wrong, and found, that webjars-locator
works through WebJarsResourceResolver
class, which's object is added in the ResourceChainRegistration.getResourceResolvers()
class method.我已经开始查看 Spring MVC 源代码以了解出了什么问题,并发现
webjars-locator
通过WebJarsResourceResolver
类工作,该类的对象添加到ResourceChainRegistration.getResourceResolvers()
类方法中。
The full sequence looks like:完整序列如下所示:
WebMvcConfigurationSupport.resourceHandlerMapping()
>> ResourceHandlerRegistration.getHandlerMapping()
>> ResourceHandlerRegistration.getRequestHandler()
>> ResourceChainRegistration.getResourceResolvers()
, where it is added as: WebMvcConfigurationSupport.resourceHandlerMapping()
>> ResourceHandlerRegistration.getHandlerMapping()
>> ResourceHandlerRegistration.getRequestHandler()
>> ResourceChainRegistration.getResourceResolvers()
,添加如下:
if (isWebJarsAssetLocatorPresent) {
result.add(new WebJarsResourceResolver());
}
The problem, is that in case of XML based configuration described above, this sequence is not invoked, neither WebMvcConfigurationSupport
class is used.问题在于,在上述基于 XML 的配置的情况下,不会调用此序列,也不会使用
WebMvcConfigurationSupport
类。
Furthermore, if I add此外,如果我添加
@EnableWebMvc
@Configuration
public class WebConfig {
}
into project, WebMvcConfigurationSupport
obviously works, but in ResourceHandlerRegistration.getHandlerMapping()
:进入项目,
WebMvcConfigurationSupport
显然有效,但在ResourceHandlerRegistration.getHandlerMapping()
:
protected AbstractHandlerMapping getHandlerMapping() {
if (registrations.isEmpty()) {
return null;
}
...
}
registrations
is empty! registrations
是空的!
After all, the only one way how to forcibly make Spring to add WebJarsResourceResolver
into the resolver chain, is:毕竟,强制 Spring 将
WebJarsResourceResolver
添加到解析器链中的唯一方法是:
1) remove <mvc:resources mapping="/webjars/**" location="/webjars/"/>
from the context.xml
and 1) 从
context.xml
删除<mvc:resources mapping="/webjars/**" location="/webjars/"/>
和
2) add addResourceHandlers
into WebConfig
: 2) 将
addResourceHandlers
添加到WebConfig
:
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry
.addResourceHandler("/webjars/**")
.addResourceLocations("/webjars/")
.setCachePeriod(3600)
.resourceChain(true) // !!! very important
;
}
My question is : what am I doing wrong?我的问题是:我做错了什么? Why XML bases configuration doesn't cause
WebJarsResourceResolver
to be registered?为什么基于 XML 的配置不会导致注册
WebJarsResourceResolver
?
Let's say that the context root path is /ctx
.假设上下文根路径是
/ctx
。 With your configuration, a resource path as /webjars/RESOURCE
is actually mapped to /ctx/webjars/RESOURCE
;通过您的配置,作为
/webjars/RESOURCE
的资源路径实际上映射到/ctx/webjars/RESOURCE
; in contrary to common expectation that it should be mapped to /webjars/RESOURCE
.与通常的预期相反,它应该映射到
/webjars/RESOURCE
。
Based on Spring 4.2.x documentation and an example similar issue , you need to map /webjars/**
to the default dispatcher servlet as:根据Spring 4.2.x 文档和类似问题的示例,您需要将
/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.
这允许将 DispatcherServlet 映射到“/”(从而覆盖容器默认 Servlet 的映射),同时仍然允许容器的默认 Servlet 处理静态资源请求。 It configures a DefaultServletHttpRequestHandler with a URL mapping of "/**" and the lowest priority relative to other URL mappings.
它使用 URL 映射“/**”和相对于其他 URL 映射的最低优先级配置 DefaultServletHttpRequestHandler。
which means adding the following should fix the issue:这意味着添加以下内容应该可以解决问题:
<mvc:resources mapping="/webjars/**" location="/webjars/">
<mvc:resource-chain>
<mvc:resource-cache />
</mvc:resource-chain>
</mvc:resources>
<mvc:annotation-driven />
<mvc:default-servlet-handler />
Another note that is the example petclinic uses location="classpath:/META-INF/resources/webjars/"
for webjars which I am not sure is relevant here.另一个注意事项是示例 petclinic使用
location="classpath:/META-INF/resources/webjars/"
作为 webjars,我不确定这里是否相关。
Hope this helps.希望这可以帮助。
Added by @Andremoniy:由@Andremoniy 添加:
for Spring 4
it has slightly different markup:对于
Spring 4
它的标记略有不同:
<mvc:resources mapping="/webjars/**" location="/webjars/">
<mvc:resource-chain resource-cache="true"/>
</mvc:resources>
This question and answer (together with https://github.com/spring-projects/spring-framework/issues/25410 ) made me find:这个问题和答案(连同https://github.com/spring-projects/spring-framework/issues/25410 )让我发现:
https://github.com/webjars/webjars/issues/1395 https://github.com/webjars/webjars/issues/1395
So I added a PR to fix the WebJars documentation:所以我添加了一个 PR 来修复 WebJars 文档:
https://github.com/webjars/webjars/pull/1946 https://github.com/webjars/webjars/pull/1946
I think this answers your question why it isn't/wasn't described in the WebJar documentation我认为这回答了您的问题,为什么它没有/没有在 WebJar 文档中描述
To answer your remaining question "why it isn't described in webjar documentation" :要回答您剩下的问题“为什么它没有在 webjar 文档中描述” :
It is/was an issue that has been reported on May 3, 2016:这是/曾经是 2016 年 5 月 3 日报告的问题:
https://github.com/webjars/webjars/issues/1395 https://github.com/webjars/webjars/issues/1395
As described on this page this issue also mentions that Spring MVC requires the resourceChain() method.如本页所述,此问题还提到 Spring MVC 需要 resourceChain() 方法。 I created a PR today to fix the issue:
我今天创建了一个 PR 来解决这个问题:
https://github.com/webjars/webjars/pull/1946 https://github.com/webjars/webjars/pull/1946
FYI: I tried to get version agnostic url's working the way it was described in the documentation but didn't succeed.仅供参考:我试图让与版本无关的 url 按照文档中描述的方式工作,但没有成功。 Along the way I also found the following issue that mentions that "The resourceChain() method must be called for version-agnostic WebJars":
在此过程中,我还发现了以下问题,其中提到“必须为与版本无关的 WebJars 调用 resourceChain() 方法”:
https://github.com/spring-projects/spring-framework/issues/25410 https://github.com/spring-projects/spring-framework/issues/25410
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.