Webjars-locator不能与基于XML的Spring MVC 4.2.x配置一起使用?

时间:2017-05-26 11:26:48

标签: java spring spring-mvc classpath webjars

我有一个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注册?

1 个答案:

答案 0 :(得分:2)

让我们说上下文根路径是/ctx。使用您的配置,/webjars/RESOURCE的资源路径实际映射到/ctx/webjars/RESOURCE;与普遍期望相反,它应该映射到/webjars/RESOURCE

基于Spring 4.2.x documentationan 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>