【问题标题】:Webjars-locator doesn't work with XML based Spring MVC 4.2.x configuration?Webjars-locator 不适用于基于 XML 的 Spring MVC 4.2.x 配置?
【发布时间】:2017-05-26 11:26:48
【问题描述】:

我有一个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() >> ResourceHandlerRegistration.getHandlerMapping() >> ResourceHandlerRegistration.getRequestHandler() >> 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) 从context.xml 中删除&lt;mvc:resources mapping="/webjars/**" location="/webjars/"/&gt;

2) 将addResourceHandlers 添加到WebConfig

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry
            .addResourceHandler("/webjars/**")
            .addResourceLocations("/webjars/")
            .setCachePeriod(3600)
            .resourceChain(true)  // !!! very important
    ;
}

我的问题是:我做错了什么?为什么基于 XML 的配置不会导致 WebJarsResourceResolver 被注册?

【问题讨论】:

    标签: java spring spring-mvc classpath webjars


    【解决方案1】:

    假设上下文根路径是/ctx。通过您的配置,/webjars/RESOURCE 的资源路径实际上 映射到 /ctx/webjars/RESOURCE;与应该映射到/webjars/RESOURCE 的普遍预期相反。

    基于Spring 4.2.x documentationan example similar issue,您需要将/webjars/** 映射到默认调度程序servlet 为:

    这允许将 DispatcherServlet 映射到“/”(从而覆盖容器默认 Servlet 的映射),同时仍然允许由容器的默认 Servlet 处理静态资源请求。它使用“/**”的 URL 映射和相对于其他 URL 映射的最低优先级配置 DefaultServletHttpRequestHandler。

    这意味着添加以下内容应该可以解决问题:

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

    【讨论】:

    • 哈!所以问题只出在&lt;mvc:resource-chain resource-cache="true"/&gt;,我不知道这种在 XML 中指定它的明显方式,谢谢!这仍然不能回答为什么 webjar 文档中没有描述它的问题,但我接受它,因为它以所需的方式解决了问题!
    【解决方案2】:

    回答你剩下的问题"why it isn't described in webjar documentation"

    这是/曾经是 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

    【讨论】:

      猜你喜欢
      • 2014-05-05
      • 2015-07-11
      • 2018-02-03
      • 1970-01-01
      • 1970-01-01
      • 2020-07-16
      • 2013-03-13
      • 1970-01-01
      • 2021-02-15
      相关资源
      最近更新 更多