servlet過濾器工作流程
servlet過濾器在request到達servlet前可以攔截,在response到達客戶端之前可以捕獲。這樣便可以在過濾器中處理一些請求響應的前置操作或通用操作。
常見的一種應用就是進行敏感詞過濾。
但是如果直接使用HttpServletResponse
,這是一個流,無法對已經out.println()
的內容進行修改。所以這裏需要替代流。
替代流(stand-in stream)
原理
在請求到達servlet之前攔截HttpServletResponse
,將HttpServletResponse
封裝成替代流,之後servlet操作的對象即是這個封裝後的替代流。這裏的封裝本質上就是建立一個輸出緩衝區,servlet的所有輸出都輸出到了這個緩衝區,並沒有直接寫入真正的HttpServletResponse
。
然後在響應返回階段,捕獲之前封裝的HttpServletResponse
,然後將servlet中輸出到緩衝區的內容,進行敏感詞過濾。
實現
利用HttpServletResponseWrapper
包裝HttpServletResponse
,並重寫輸出流的方法。
一種實現方法如下:
public class BufferedResponse extends HttpServletResponseWrapper {
private PrintWriter printWriter;
private CharArrayWriter charArrayWriter;
public BufferedResponse(HttpServletResponse response) {
super(response);
charArrayWriter = new CharArrayWriter();
printWriter = new PrintWriter(bufferedWriter);
}
@Override
public PrintWriter getWriter() {
return printWriter;
}
public String getOutput() {
return charArrayWriter.toString();
}
}
過濾器中使用:
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
BufferedResponse bufferedResponse = new BufferedResponse(servletResponse);
// filterChain.doFilter 這裏指繼續處理後續步驟
filterChain.doFilter(servletRequest, bufferedResponse);
//這裏servlet已經處理完,output即servlet的輸出,在這裏替換敏感詞
String output = bufferedResponse.getOutput();
}
以及如果對CharArrayWriter陌生,點擊這裏 CharArrayWriter