2012-10-02 80 views
1

我希望在doFilter()函數完成運行後添加HTTP標頭。在doFilter後更新響應

public void doFilter(ServletRequest request, ServletResponse response, 
        FilterChain chain) throws IOException, ServletException { 
    HttpServletResponse httpResp = (HttpServletResponse) response; 

    try { 
    chain.doFilter(request, httpResp); 

    } finally {   
    httpResp.setHeader("ADD A HEADER: ", "HEADER"); 
    }          
} 

看來,doFilter刷新響應。


UPDATE:

感謝。觀看IgorMadjeric和richardtz答案後,我決定嘗試響應包裝:


這是包裝:

public class BufferedHttpServletResponse extends HttpServletResponseWrapper { 

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

public void flushBuffer() { 
    System.out.println("flush"); 
} 

}

這是更改後的代碼:

public void doFilter(ServletRequest request, ServletResponse response, 
        FilterChain chain) throws IOException, ServletException { 
    HttpServletResponse httpResp = (HttpServletResponse) response; 

    try { 
     BufferedHttpServletResponse bufferedResponse = new BufferedHttpServletResponse(httpResp); 
     chain.doFilter(request, bufferedResponse); 

    } finally {   
     bufferedResponse.setHeader("ADD A HEADER: ", "HEADER"); 
    }          
} 

仍不工作。我做錯什麼了嗎?

+1

爲什麼你需要在'doFilter()'後執行它? – axtavt

+0

我想添加性能數據,它似乎是正確的地方做到這一點。 –

+0

我有添加性能信息的類似問題。它可能取決於容器何時提交響應,並且您可能無法控制它。我最終做的是將這些信息添加到html響應中(這是我生成的html)到響應的主體。此外,只有在請求中包含某些參數時纔會生成性能信息。 – richardtz

回答

1

正如在評論和this問題中已經提到的,它可能不足以覆蓋flushBuffer(),但您還需要覆蓋getWriter()和getOutputStream()。在某些情況下,甚至可能還不夠。例如,如果sendError(int)在響應上被調用,它也可以被提交。

0

在你的情況從您發佈的代碼,你不能說:

似乎doFilter的刷新響應。

有一些關於提交響應的規則。

響應在過濾後可能已由某個組件提交。

如果你想避免這種行爲,你應該使用請求/響應包裝器,這將阻止你的過濾器應用於提交響應的組件。

+0

謝謝,試了一下,它沒有工作。我更新了問題的主體。 –

+0

僅當調用flush方法時纔會提交響應。當緩衝區滿時,響應也會自動提交。 想想如何覆蓋getOutputStream()和getWriter()方法 – IgorMadjeric

3

一旦刷新/提交(它已經被髮送到客戶端),你不能修改頭的響應。

doFilter不刷新響應,但執行請求時很多事情可能導致它。 (顯式調用response.flush(),響應中的主體太大),並且您無法控制它。

但是,您可以使用HttpServletResponseWrapper來更改此設置。

希望它有幫助。

+0

我需要根據內容類型設置響應頭。有關如何這樣做的任何想法? –

+0

@Arjun,你可以在設置內容類型後立即設置標題(內容類型也是一個標題,所以如果你可以設置它,你也可以設置其他標題) – richardtz

+0

我只想設置響應標題如果content-type是「text/html」。我沒有在我的代碼中設置內容類型。我正在設置緩存控制。 –