HttpServletResponseWrapper为我们实现对response对象的后处理提供了帮助——你只需编写一个HttpServletResponseWrapper的子类,加入自己的功能实现(修饰器模式)。那么子类化HttpServletResponseWrapper都需要重写那些方法呢?
1、获取response对象,并将输出存放在自定义的流里面,那么关于输出流(outputStream、writer)的操作都是需要重写的了:
1)以流的方式获取输出——重写getOutputStream()
2)以字符方式获取输出——重写getWriter()
3)刷新流——重写flushBuffer()
4)重置流——重写reset()
然后加入新增的获取输出数据的方法就ok了。
2、定义response包装器WapperedResponse继承HttpServletResponseWrapper
public class WapperedResponse extends HttpServletResponseWrapper { private ByteArrayOutputStream buffer=null; private ServletOutputStream out=null; private PrintWriter writer=null; public WapperedResponse(HttpServletResponse resp) throws IOException{ super(resp); buffer=new ByteArrayOutputStream();//真正存储数据的流 out=new WapperedOutputStream(buffer); writer=new PrintWriter(new OutputStreamWriter(buffer,this.getCharacterEncoding())); } //重载父类获取outputstream的方法 @Override public ServletOutputStream getOutputStream()throws IOException{ return out; } //重载父类获取writer的方法 @Override public PrintWriter getWriter() throws UnsupportedEncodingException{ return writer; } //重载父类获取flushBuffer的方法 @Override public void flushBuffer()throws IOException{ if(out!=null){ out.flush(); } if(writer!=null){ writer.flush(); } } @Override public void reset(){ buffer.reset(); } public byte[] getResponseData()throws IOException{ flushBuffer();//将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据 return buffer.toByteArray(); } //内部类,对ServletOutputStream进行包装 private class WapperedOutputStream extends ServletOutputStream{ private ByteArrayOutputStream bos=null; public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException{ bos=stream; } @Override public void write(int b) throws IOException{ bos.write(b); } } }
那么Servlet容器通过调用getOutputStream()方法获得的输出流将是我们自定义的包装流WapperedOutputStream。
3、现在就可以在过滤器中使用WapperedResponse进行对response包装、处理了。
public void doFilter(ServletRequest arg0, ServletResponse arg1, FilterChain arg2) throws IOException, ServletException { HttpServletResponse resp=(HttpServletResponse)arg1; WapperedResponse wapper=new WapperedResponse(resp); arg2.doFilter(arg0, wapper); byte[] b1=wapper.getResponseData(); //do something with b1 here byte[] b2=...; //输出处理后的数据 ServletOutputStream output=arg1.getOutputStream(); output.write(b2); output.flush(); }