Java 如何使用Spring缓存控件删除Expires标头

Java 如何使用Spring缓存控件删除Expires标头,java,spring,http,spring-mvc,spring-security,Java,Spring,Http,Spring Mvc,Spring Security,默认情况下,Spring Security会添加以下缓存头: Cache-Control: no-cache, no-store, max-age=0, must-revalidate Pragma: no-cache Expires: 0 对于我们的HTML页面来说,这是一个很好的设置。对于静态资源(图像、CSS等),我们希望缓存它们。根据,可以如下配置: @EnableWebMvc public class WebMvcConfiguration extends WebMvcConfigu

默认情况下,Spring Security会添加以下缓存头:

Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
对于我们的HTML页面来说,这是一个很好的设置。对于静态资源(图像、CSS等),我们希望缓存它们。根据,可以如下配置:

@EnableWebMvc
public class WebMvcConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry
            .addResourceHandler("/resources/**")
            .addResourceLocations("/resources/")
            .setCachePeriod(31556926);
    }
}
这将导致以下HTTP头:

Cache-Control: max-age=604800
Pragma: 
Expires: 0
这很好,除了
Expires
头,它仍然指示不应该缓存文档。(标准规定
max age
优先于
Expires
。但我们的中间缓存仍将其视为不可缓存。)


如何删除可缓存文档的
Expires
标题(或将其设置为空)?如果配置缓存周期,为什么Spring不删除它?

ResourceHttpRequestHandler.useExpriresHeader
设置为
false

不幸的是,在配置对象
ResourceHandlerRegistry
中没有这样的标志。因此,您需要自己动手:

以下只是一个想法,我没有检查此方法是否配置了
ResourceHttpRequestHandler
之外的任何其他
HandlerMapping

@Override
@Bean
public HandlerMapping resourceHandlerMapping() {
    ResourceHandlerRegistry registry = new ResourceHandlerRegistry(this.applicationContext, this.servletContext);
    addResourceHandlers(registry);

    AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
    if (handlerMapping != null) {
        handlerMapping.setPathMatcher(mvcPathMatcher());
        handlerMapping.setUrlPathHelper(mvcUrlPathHelper());
        handlerMapping.setInterceptors(new HandlerInterceptor[] {
                new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider())});

        //this line!!!:
        ((ResourceHttpRequestHandler)handlerMapping).setUseExpiresHeader(false);
    }
    else {
        handlerMapping = new EmptyHandlerMapping();
    }
    return handlerMapping;
}

这似乎与此有关。您可以通过忽略上列出的特定URL来解决此问题(有些不相关)。但是,不建议这样做(即使URL指向静态资源),因为这意味着禁用URL的所有安全性

相反,用户应该考虑使用这个解决方案:

@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        RequestMatcher notResourcesMatcher = new NegatedRequestMatcher(new AntPathRequestMatcher("/resources/**"));
        HeaderWriter notResourcesHeaderWriter = new DelegatingRequestMatcherHeaderWriter(notResourcesMatcher , new CacheControlHeadersWriter());
        http
            .headers()
                .cacheControl().disable()
                .addHeaderWriter(notResourcesHeaderWriter);
    }
}

当Spring Security 4.1发布时,它将被修复,这不应该是一个问题。

默认情况下,它是错误的。此外,
useExpiresHeader
已被弃用。所以这段代码不会改变任何东西。我的调试还显示,Spring Security在请求处理的早期插入Expires头。因此,
ResourceHttpRequestHandler
需要主动取消设置它。将其设置为true可能更有意义……您使用的是哪个版本的SpringWeb?如果您使用的是spring-web-4.2.5.RELEASE.jar,那么您可能会遇到同样的问题。您可以看看spring-web-4.2.4.RELEASE.jar是否也会出现同样的问题。我们仍然使用的是4.2.4。所以它与SPR-14005无关。然而,在bug的一条评论中,有一个示例说明了如何从SpringSecurity中排除某些资源。这是一个有效的解决方案。是否要添加is作为答案?谢谢你的链接。谢谢你的回复和反馈。请不要在那个JIRA上使用变通方法。详情见下面我的答案