如何在Spring 4.2或更高版本中设置Cache-control:private与applicationContext.xml

问题描述:

如何在Spring 4.2或更高版本中使用applicationContext.xml设置Cache-control:private?如何在Spring 4.2或更高版本中设置Cache-control:private与applicationContext.xml

背景:

Cache-control: HTTP标头可以从applicationContext.xml春季4.1这样设置:

<mvc:interceptors> 
    <bean id="webContentInterceptor" 
     class="org.springframework.web.servlet.mvc.WebContentInterceptor"> 
    <property name="cacheSeconds" value="0"/> 
    <property name="useExpiresHeader" value="true"/> 
    <property name="useCacheControlHeader" value="true"/> 
    <property name="useCacheControlNoStore" value="true"/> 
    </bean> 
</mvc:interceptors> 

有一些基于注解实现比如https://github.com/foo4u/spring-mvc-cache-control,但我更喜欢基于XML的配置,因为我有根据测试/生产环境更改HTTP标头(例如,如果页面以Cache-Control: private, no-store, no-cache, must-revalidate返回,并使反CSRF标记不匹配,则Chrome会发送另一个“查看页面源”请求)。

问题:

从Spring 4.2开始,这些设置不推荐使用。 此外,Cache-control: private不能从这些设置中设置。由于某些CDN提供商不存储内容,当且仅当http头包含Cache-Control: private时,对于使用CDN的系统,此HTTP头的支持才是关键。例如http://tech.mercari.com/entry/2017/06/22/204500https://community.fastly.com/t/fastly-ttl/882

所以我正在寻找方法来设置Cache-Control:来自applicationContext.xml的私人HTTP头,以保证安全。

在Spring 4.2+中似乎没有XML即用即用的支持。正如你可以看到herecacheControlMappings没有set方法的WebContentInterceptor,所以没有机会从XML配置写入值到它;而这张地图旨在存储url-cache-control映射。但是,CacheControl类拥有公共cachePrivate方法,可以用于注册自定义配置(我认为可以对dev或prod配置文件进行配置);例如:

@Override 
public void addResourceHandlers(ResourceHandlerRegistry registry) { 
    CacheControl cacheControl = CacheControl.empty().cachePrivate(); 
    registry.addResourceHandler("/**") 
       .setCacheControl(cacheControl); 
} 
在控制器

或者直接(可能是依赖于活动的配置文件太):

@RequestMapping(value = "/test") 
public ResponseEntity<?> doHandleRequest() { 
    CacheControl cacheControl = CacheControl.empty().cachePrivate(); 
    return ResponseEntity.ok() 
         .cacheControl(cacheControl); 
} 

如果你一定需要利用XML配置,没有人阻止你编写的WebContentInterceptor自定义子类用适当的方法和逻辑,幸运的是,WebContentInterceptoraddCacheMapping方法。

+0

谢谢您的建议。 'CacheControl.cachePrivate()'似乎将'private'设置为'Cache-control:'头部。 但我发现了另一个问题。我想在Struts中设置所有no-cache,no-store和max-age = 0,如nocache =“true”。另一方面,CacheControl.noCache(),noStore()和maxAge()都是静态方法,并且不返回它。所以我无法通过CacheControl设置所有这些标题... – satob

+0

是的,似乎是'CacheControl'类中的某种错误设计... – arcquim

+0

感谢您的信息。概括来说: - Spring 4.2+中没有XML开箱即用的“Cache-Control:private”支持。 - 你可以使用'setCacheControl'来设置'Cache-Control'头。 - Spring中的'CacheControl'类有一些设计问题。 – satob