在做Tomcat过滤器与包装类的例子时,发现在doFilter函数里取不到response的数据,总是达不到预想的输出,最终发现问题所在:
1、doFilter能实现请求和响应过滤是靠chain.doFilter函数实现的,所以该函数的调用位置很重要,在chain.doFilter调用以后,response才会有数据;
2、chain.doFilter函数的参数要用包装后的类,否则请求和响应的执行路径就变了;
3、自己太二。
下面是过滤器执行代码:
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
// TODO Auto-generated method stub
// place your code here
HttpServletResponse res = (HttpServletResponse)response;
MyWrapper resw = new MyWrapper(res);
// pass the request along the filter chain
chain.doFilter(request, resw);
String str = resw.getStringWriter().toString();
str = str.replaceFirst("色情", "**");
PrintWriter out = resw.getResponse().getWriter();
out.write(str);
out.flush();
out.close();
}
下面是响应包装类代码:
public class MyWrapper extends HttpServletResponseWrapper {
private StringWriter sw = new StringWriter();
public MyWrapper(HttpServletResponse response) {
super(response);
// TODO Auto-generated constructor stub
}
public PrintWriter getWriter() throws IOException{
return new PrintWriter(sw);
}
public StringWriter getStringWriter() {
return sw;
}
}
客户端发出的请求首先经过过滤器,然后到servlet,经过servlet处理后又回到过滤器,最终到客户端处理。两次经过过滤器的过程在Tomcat代码中是由doFilter中chain.doFilter调用实现的。
请求从客户端发出到过滤器后,可以在doFilter函数中先进行一些预处理,比如把response进行包装,此时response还没有经过servlet处理,是没有输出的数据的,然后调用chain.doFilter继续执行其他过滤器,直到servlet处理完请求,chain.doFilter函数返回,继续执行chain.doFilter后的代码,这时response中就有处理的数据了。