2012-11-14 85 views
4

我有我的應用程序部署總是返回響應頭一個問題:什麼是在我的部署中設置Cache-Control no-cache,no-store?

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

JB OSS AS 7.0.1



我已經試過幾乎在應用程序端每一個解決方案,我可以找到:

  1. 配置WebContentInterceptor(試過它的各種排列)Right out of the box cache-control header filter?
  2. 寫自定義攔截器,添加不同的Cache-Control標頭(使用Cache-Control:private進行測試)
  3. 編寫添加HTTP響應參數的客戶過濾器。使用Cache-Control配置它:private作爲web.xml中的init-params
  4. 使用context.xml文件(在META-INF /和WEB-INF /中都試過)禁用JBoss/Tomcat中的緩存控制http://daveharris.wordpress.com/2007/07/09/how-to-configure-cache-control-in-tomcat/

在上述所有情況下,響應報頭永遠結束了一樣,總是無緩存,無店鋪,1970年到期,編譯:無緩存

我跑出來的想法,有誰知道什麼是我的響應中設置這些標題,所以我可以定位適當的部署組件來解決這個問題?

回答

5

導致此問題的根代碼位於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 Headers。事實證明,我已經擴展了JsfFlowHandlerAdapter來處理FlowExecutionRestorationFailureException(請參閱Sping Web Flow Preventing Back Button Use),所以我需要做的就是設置我想要的配置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; 
    } 
}