这里想说明一个问题,就是所有响应的内容都在respones里,我们i可以在过滤器这里获取到response里所有的内容。我可以看到servlet和filter中的方法都是没有返回值的,他们只是负责操作request和response,对response的操作就是把我们想要给浏览器的内容放到response里,然后tomcat会把response返回给浏览器。我们所有的响应内容不管是重定向还是转发还是通过response获取流后进写操作(其实转发也是通过获取response流把内容写到response里的。),最终都是把内容写到reponse后由tomcat返回给浏览器的。
请求过来后,tomcat帮我们创建好request假设是A对象和response假设是B对象,然后把tomcat调用filter和servlet中的方法并把对象传递给filter servlet中的方法参数里。我们通过filter和servlet操作request即A对象和response即B对象里的内容,我们操作完后即filter和servlet中的方法执行完后,tomcat对filter和servlet调用完毕,这时request即A对象和response即B对象里的内容都变成我们操作后的内容了。tomcat再把response即B对象(还是之前tomcat帮我们创建的对象只是对象里的内容变成我们通过filter和serlvet方法操作后的内容了)返回给浏览器。 因为tomcat传给servlet和filter的response 不能获取到response里的内容,所以我们可以在filter中对tomcat的response进行包装,我们可以自己定义一个继承自HttpServletResponseWrapper的类,然后在里面把我们自己定义的writer流和outpustream流替换原先的流。再在filter中用我们的自定义的HttpServletResponseWrapper的子类对response进行包装,将包装后的response传到dofilter(request,response)方法中,这样后端的过滤器和servlet中获取到的response就是我们自己包装后的response,那么后面的filter和servlet都在使用我们包装后的response,我们就可以通过我们的response获得response里的内容了。
第一步包装类: 下面的类只是替换了writer没有替换outputstrem,所以我们只能获取到后端使用gerWriter方法写的内容。
package respones;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
public class WrapperResponse extends HttpServletResponseWrapper {
private MyPrintWriter tmpWriter;
private ByteArrayOutputStream output;
public WrapperResponse(HttpServletResponse httpServletResponse) {
super(httpServletResponse);
output = new ByteArrayOutputStream();
tmpWriter = new MyPrintWriter(output);
}
public void finalize() throws Throwable {
super.finalize();
output.close();
tmpWriter.close();
}
public String getContent() {
try {
tmpWriter.flush(); //刷新该流的缓冲,详看java.io.Writer.flush()
String s = tmpWriter.getByteArrayOutputStream().toString("UTF-8");
//此处可根据需要进行对输出流以及Writer的重置操作
//比如tmpWriter.getByteArrayOutputStream().reset()
return s;
} catch (UnsupportedEncodingException e) {
return "UnsupportedEncoding";
}
}
//覆盖getWriter()方法,使用我们自己定义的Writer
public PrintWriter getWriter() throws IOException {
return tmpWriter;
}
public void close() throws IOException {
tmpWriter.close();
}
//自定义PrintWriter,为的是把response流写到自己指定的输入流当中
//而非默认的ServletOutputStream
private static class MyPrintWriter extends PrintWriter {
ByteArrayOutputStream myOutput; //此即为存放response输入流的对象
public MyPrintWriter(ByteArrayOutputStream output) {
super(output);
myOutput = output;
}
public ByteArrayOutputStream getByteArrayOutputStream() {
return myOutput;
}
}
}
filter类:
package respones;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebFilter("/*")
public class GavinFilter implements Filter {
@Override
public void destroy() {
// TODO 自动生成方法存根
}
@Override
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) arg0;
HttpServletResponse response = (HttpServletResponse) arg1;
WrapperResponse wrapperResponse = new WrapperResponse(response);
chain.doFilter(request, wrapperResponse);
String html = wrapperResponse.getContent();
response.getWriter().print(html);
System.out.println(html);
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO 自动生成方法存根
}
}