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

时间:2017-09-11 15:31:00

标签: java xml spring spring-mvc caching

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

背景:

Cache-control:可以在Spring 4.1中从applicationContext.xml设置HTTP标头,如下所示:

<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标头(例如,Chrome发送另一个请求&#34;查看页面源& #34;如果页面返回Cache-Control: private, no-store, no-cache, must-revalidate,并使反CSRF令牌不匹配。

问题:

自Spring 4.2起,这些设置已弃用。 此外,无法从这些设置中设置Cache-control: private。因为当且仅当http头包含Cache-Control: private时,某些CDN提供程序不存储内容,因此对此HTTP头的支持对于使用CDN的系统至关重要。例如http://tech.mercari.com/entry/2017/06/22/204500https://community.fastly.com/t/fastly-ttl/882

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

2 个答案:

答案 0 :(得分:2)

在Spring 4.2+中似乎没有XML开箱即用的支持。如您所见[{3}},set cacheControlMappings没有WebContentInterceptor方法,因此无法将XML配置中的值写入其中;此映射用于存储url-cache-control映射。但是,here类具有公共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的自定义子类,幸运的是,WebContentInterceptor具有addCacheMapping方法。

答案 1 :(得分:1)

如果必须使用XML配置(如我所必须),则可以按以下步骤实现它-

通过首先调用为您创建bean的工厂方法来创建XML的CacheControl bean。在您的情况下,您需要一个空的CacheControl以-

开头
<bean id="cacheControlFactory" class="org.springframework.http.CacheControl" factory-method="empty" />

现在借助cachePrivate调用CacheControl实例的org.springframework.beans.factory.config.MethodInvokingFactoryBean方法-

<bean id="myCacheControl" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
    <property name="targetObject">
        <ref bean="cacheControlFactory"/>
    </property>
    <property name="targetMethod">
        <value>cachePrivate</value>
    </property>
</bean>

现在使用保存您的配置的最终bean,并调用addCacheMapping的{​​{1}}方法,您就完成了。此配置将应用于您以varargs参数-

中的列表形式发送的网址
webContentInterceptor

可以在此SO线程中找到有效的xml配置-How to set cacheControlMappings in WebContentInterceptor in Spring 5 Xml