2010-04-01 28 views
8

我想爲所有image/*text/css設置Expires標頭。我正在做這個Filter。但是:如何添加基於內容類型的響應標頭;在提交響應之前獲取Content-type

  • 主叫內容類型還沒有「意識到」
  • 主叫內容類型被設置之後,但這樣是內容長度,即禁止增加新的報頭(至少在之前Tomcat的實現)

我可以使用所請求的資源的擴展,但由於某些CSS文件由RichFaces的產生由內JAR-文件服用它們,文件的名稱不是x.css,但是/xx/yy/zz.xcss/DATB/...

那麼,有沒有辦法在提交響應之前獲取Content-type。

回答

13

是的,執行HttpServletResponseWrapper並覆蓋setContentType()

class AddExpiresHeader extends HttpServletResponseWrapper { 
    private static final long ONE_WEEK_IN_MILLIS = 604800000L; 

    public AddExpiresHeader(HttpServletResponse response) { 
     super(response); 
    } 

    public void setContentType(String type) { 
     if (type.startsWith("text") || type.startsWith("image")) { 
      super.setDateHeader("Expires", System.currentTimeMillis() + ONE_WEEK_IN_MILLIS); 
     } 
     super.setContentType(type); 
    } 
} 

和按如下方式使用它:

chain.doFilter(request, new AddExpiresHeader((HttpServletResponse) response)); 
+0

當然..我應該想到這個..尤其是當在同一個過濾器中使用另一個包裝(因爲另一個原因).. :) – Bozho 2010-04-01 20:51:09

+0

(只有,它不會是0,而是未來的一個時間) – Bozho 2010-04-01 20:58:13

+0

當然可以。或者你使用JodaTime? ;) – BalusC 2010-04-01 21:02:48

2

您應該繼承HttpServletResponseWrapper並覆蓋addHeadersetHeader,以在傳入「Content-Type」作爲標題名稱時添加新的所需標題。請確保不要忘記在那些重寫的方法中也調用super。用這個新的Wrapper包裝doFilter方法參數中發送的響應,並將Wrapper傳遞給doFilter的調用。

+0

(+1)你和BalusC的答案都是正確的解決方案,但他是一個有點清潔(至少對我來說,因爲一個不所謂一般方法被覆蓋) – Bozho 2010-04-01 20:52:24

+0

是的,我錯過了setContentType方法。您可能會考慮對setHeader和addHeader執行相同的操作,因爲您永遠不知道它是如何編碼的。除非你擁有所有的代碼。 – laz 2010-04-01 21:13:15