【问题标题】:What is setting Cache-Control no-cache, no-store in my deployment?在我的部署中设置 Cache-Control no-cache, no-store 是什么?
【发布时间】:2012-11-03 06:44:48
【问题描述】:

我有一个问题,我的应用程序部署总是返回响应标头:

Cache-Control: no-cache
Cache-Control: no-store
Expires:Thu, 01 Jan 1970 00:00:00 GMT
Pragma:no-cache



我正在使用:

春季 3.1.2.RELEASE

Primefaces JSF 3.4.1

Spring Webflow 2.3.0.RELEASE

JBoss AS 7.0.1



我已经尝试了几乎所有我能找到的应用程序方面的解决方案:

  1. 配置 WebContentInterceptor(尝试了它的各种排列)Right out of the box cache-control header filter?
  2. 编写自定义拦截器,添加不同的 Cache-Control 标头(使用 Cache-Control: private 测试)
  3. 编写添加 HTTP 响应参数的客户过滤器。在 web.xml 中使用 Cache-Control: private as init-params 配置它
  4. 使用 context.xml 文件(在 META-INF/ 和 WEB-INF/ 中都尝试过)禁用 JBoss/Tomcat 中的 Cache-Control http://daveharris.wordpress.com/2007/07/09/how-to-configure-cache-control-in-tomcat/

在上述所有情况下,响应头永远不会不同,总是 no-cache、no-store、1970 expires、pragma: no-cache

我的想法已经不多了,有谁知道在我的响应中设置这些标头是什么,以便我可以针对适当的部署组件来解决这个问题?

【问题讨论】:

    标签: java spring jboss primefaces spring-webflow


    【解决方案1】:

    导致这种情况的根代码在 Spring MVC 中,从 WebContentGenerator 调用。该类用作 MVC/Webflow 堆栈中几个类的基类:WebContentInterceptor(MVC 拦截器)、AbstractController(MVC 控制器)、AbstractHandlerMethodAdapter(MVC HandlerAdapter)、AnnotationMethodHadlerAdapter(MVC HandlerAdapter)、FlowHandlerAdapter(Webflow HandlerAdapter)、JsfFlowHandlerAdapter(Webflow + JSF HandlerAdapter)

    CacheControl 秒设置为 0 调用 preventCaching 方法。所以看起来应用程序默认设置为 0。

    org.springframework.web.servlet.support.WebContentGenerator

    protected final void preventCaching(HttpServletResponse response) {
        response.setHeader(HEADER_PRAGMA, "no-cache");
        if (this.useExpiresHeader) {
            // HTTP 1.0 header
            response.setDateHeader(HEADER_EXPIRES, 1L);
        }
        if (this.useCacheControlHeader) {
            // HTTP 1.1 header: "no-cache" is the standard value,
            // "no-store" is necessary to prevent caching on FireFox.
            response.setHeader(HEADER_CACHE_CONTROL, "no-cache");
            if (this.useCacheControlNoStore) {
                response.addHeader(HEADER_CACHE_CONTROL, "no-store");
            }
        }
    }
    

    我发现由于我使用的是 JSF + Webflow,因此 JsfFlowHandlerAdapter 首先处理服务器对流/视图的请求。这就是为什么配置拦截器没有帮助的原因,因为此时 JsfFlowHandlerAdapter 已经设置了 Cache-Control 和其他 HTTP 标头。原来我已经扩展了 JsfFlowHandlerAdapter 来处理 FlowExecutionRestorationFailureException(参见 Sping Web Flow Preventing Back Button Use)所以我需要做的就是设置我想要的配置 ala WebContentInterceptor(因为配置属于基类 WebContentGenerator)。

    自定义 JsfFlowHandlerAdapter

    public class MyAppFlowHandlerAdapter extends org.springframework.faces.webflow.JsfFlowHandlerAdapter {
         ...
        }
    

    webmvc-config.xml

    <!-- Dispatches requests mapped to flows to FlowHandler implementations -->
        <bean
            class="com.myapp.MyAppFlowHandlerAdapter">
            <property name="flowExecutor" ref="flowExecutor" />
                <!-- Disable built in Cache-Control settings -->
            <property name="cacheSeconds" value="-1" />
            <property name="useExpiresHeader" value="false" />
            <property name="useCacheControlHeader" value="false" />
            <property name="useCacheControlNoStore" value="false" />
        </bean>
    
    <!-- Maps request paths to flows in the flowRegistry; e.g. a path of /hotels/booking 
        looks for a flow with id "hotels/booking" -->
    <bean class="org.springframework.webflow.mvc.servlet.FlowHandlerMapping">
        <!-- snip out unimportant -->
        <property name="interceptors">
            <list>
                <ref bean="cacheControlInterceptor" />  
            </list>
        </property>
    </bean>
        <bean id="cacheControlInterceptor"
        class="com.myapp.CacheControlInterceptor">
    

    CacheControlInterceptor(设置您自己的 HTTP 标头。在 WebContentGenerator 中执行此操作的方法是最终的,因此不能@Override)

    public class CacheControlInterceptor extends HandlerInterceptorAdapter {
    
        @Override
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
                //Example below: set your Cache-Control, expires, pragma headers here
            response.setHeader("Cache-Control", "private");
    
            return true;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2022-11-17
      • 2011-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-12-09
      • 2011-01-25
      相关资源
      最近更新 更多