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