filter过滤器使用HttpServletResponseWrapper操作Response对象

有时我们希望在请求输出之前对response对象进行一些额外的操作,比如从response读出相应的数据,并持久化到数据库中,最后再发往客户端,但由于response输出流对象没有Buffer功能,且只能读取一次,幸好我们可以通过继承HttpServletResponseWrapper类来达到我们的需求。下面就具本通过实现此类来完成上面提到的功能。 
HttpServletResponseWrapper为我们实现对response对象的后处理提供了帮助,你只需编写一个HttpServletResponseWrapper的子类,加入自己的功能实现(修饰器模式)。那么子类化 HttpServletResponseWrapper都需要重写那些方法呢? 

1、获取response对象,并将输出存放在自定义的流里面,那么关于输 出流(outputStream、writer)的操作都是需要重写的了: 
1)以流的方式获取输出——重写getOutputStream() //返回一般为打印流,其底层是对ServletOutputStream引用。 
2)以字符方式获取输出——重写getWriter() //直接对ServletOutputStream的引用 
3)刷新流——重写flushBuffer() 
4)重置流——重写reset() 

然后加入新增的获取输出数据的方法就ok了。 
2、定义response包装器WapperedResponse继承HttpServletResponseWrapper 


    
    
  1. public class WrapperedResponse extends HttpServletResponseWrapper {
  2. private ByteArrayOutputStream buffer = null;
  3. private ServletOutputStream out = null;
  4. private PrintWriter writer = null;
  5. public WrapperedResponse(HttpServletResponse resp) throws IOException {
  6. super(resp);
  7. buffer = new ByteArrayOutputStream(); // 真正存储数据的流
  8. out = new WapperedOutputStream(buffer);
  9. writer = new PrintWriter( new OutputStreamWriter(buffer, this.getCharacterEncoding()));
  10. }
  11. /**重载父类获取outputstream的方法*/
  12. @Override
  13. public ServletOutputStream getOutputStream() throws IOException {
  14. return out;
  15. }
  16. /**重载父类获取writer的方法*/
  17. @Override
  18. public PrintWriter getWriter() throws UnsupportedEncodingException {
  19. return writer;
  20. }
  21. /**重载父类获取flushBuffer的方法*/
  22. @Override
  23. public void flushBuffer() throws IOException {
  24. if (out != null) {
  25. out.flush();
  26. }
  27. if (writer != null) {
  28. writer.flush();
  29. }
  30. }
  31. @Override
  32. public void reset() {
  33. buffer.reset();
  34. }
  35. /**将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据*/
  36. public byte[] getResponseData() throws IOException {
  37. flushBuffer();
  38. return buffer.toByteArray();
  39. }
  40. /**内部类,对ServletOutputStream进行包装*/
  41. private class WapperedOutputStream extends ServletOutputStream {
  42. private ByteArrayOutputStream bos = null;
  43. public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException {
  44. bos = stream;
  45. }
  46. @Override
  47. public void write(int b) throws IOException {
  48. bos.write(b);
  49. }
  50. @Override
  51. public void write(byte[] b) throws IOException {
  52. bos.write(b, 0, b.length);
  53. }
  54. }
  55. }



上面是我们对HttpServletResponseWrapper的包装。随后我们可以编写自已一Filter来完成实现的工作。 

    
    
  1. @Override
  2. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  3. log.info( "begin filter invoke!");
  4. WrapperedResponse wrapResponse = new WrapperedResponse((HttpServletResponse)response);
  5. chain.doFilter(request, wrapResponse);
  6. byte[] data = wrapResponse.getResponseData();
  7. log.info( "原始数据: " + new String(data));
  8. String tempData = new String( "jack");
  9. ServletOutputStream out = response.getOutputStream();
  10. out.write(tempData.getBytes());
  11. out.flush();
  12. log.info( "end filter invoke!");
  13. }


这样在页面上调用后将会输出我们修改后的结果如上例为:jack  
有时我们希望在请求输出之前对response对象进行一些额外的操作,比如从response读出相应的数据,并持久化到数据库中,最后再发往客户端,但由于response输出流对象没有Buffer功能,且只能读取一次,幸好我们可以通过继承HttpServletResponseWrapper类来达到我们的需求。下面就具本通过实现此类来完成上面提到的功能。 
HttpServletResponseWrapper为我们实现对response对象的后处理提供了帮助,你只需编写一个HttpServletResponseWrapper的子类,加入自己的功能实现(修饰器模式)。那么子类化 HttpServletResponseWrapper都需要重写那些方法呢? 

1、获取response对象,并将输出存放在自定义的流里面,那么关于输 出流(outputStream、writer)的操作都是需要重写的了: 
1)以流的方式获取输出——重写getOutputStream() //返回一般为打印流,其底层是对ServletOutputStream引用。 
2)以字符方式获取输出——重写getWriter() //直接对ServletOutputStream的引用 
3)刷新流——重写flushBuffer() 
4)重置流——重写reset() 

然后加入新增的获取输出数据的方法就ok了。 
2、定义response包装器WapperedResponse继承HttpServletResponseWrapper 


  
  
  1. public class WrapperedResponse extends HttpServletResponseWrapper {
  2. private ByteArrayOutputStream buffer = null;
  3. private ServletOutputStream out = null;
  4. private PrintWriter writer = null;
  5. public WrapperedResponse(HttpServletResponse resp) throws IOException {
  6. super(resp);
  7. buffer = new ByteArrayOutputStream(); // 真正存储数据的流
  8. out = new WapperedOutputStream(buffer);
  9. writer = new PrintWriter( new OutputStreamWriter(buffer, this.getCharacterEncoding()));
  10. }
  11. /**重载父类获取outputstream的方法*/
  12. @Override
  13. public ServletOutputStream getOutputStream() throws IOException {
  14. return out;
  15. }
  16. /**重载父类获取writer的方法*/
  17. @Override
  18. public PrintWriter getWriter() throws UnsupportedEncodingException {
  19. return writer;
  20. }
  21. /**重载父类获取flushBuffer的方法*/
  22. @Override
  23. public void flushBuffer() throws IOException {
  24. if (out != null) {
  25. out.flush();
  26. }
  27. if (writer != null) {
  28. writer.flush();
  29. }
  30. }
  31. @Override
  32. public void reset() {
  33. buffer.reset();
  34. }
  35. /**将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据*/
  36. public byte[] getResponseData() throws IOException {
  37. flushBuffer();
  38. return buffer.toByteArray();
  39. }
  40. /**内部类,对ServletOutputStream进行包装*/
  41. private class WapperedOutputStream extends ServletOutputStream {
  42. private ByteArrayOutputStream bos = null;
  43. public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException {
  44. bos = stream;
  45. }
  46. @Override
  47. public void write(int b) throws IOException {
  48. bos.write(b);
  49. }
  50. @Override
  51. public void write(byte[] b) throws IOException {
  52. bos.write(b, 0, b.length);
  53. }
  54. }
  55. }



上面是我们对HttpServletResponseWrapper的包装。随后我们可以编写自已一Filter来完成实现的工作。 

  
  
  1. @Override
  2. public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
  3. log.info( "begin filter invoke!");
  4. WrapperedResponse wrapResponse = new WrapperedResponse((HttpServletResponse)response);
  5. chain.doFilter(request, wrapResponse);
  6. byte[] data = wrapResponse.getResponseData();
  7. log.info( "原始数据: " + new String(data));
  8. String tempData = new String( "jack");
  9. ServletOutputStream out = response.getOutputStream();
  10. out.write(tempData.getBytes());
  11. out.flush();
  12. log.info( "end filter invoke!");
  13. }


这样在页面上调用后将会输出我们修改后的结果如上例为:jack  

猜你喜欢

转载自blog.csdn.net/sunjinjuan/article/details/80975489
今日推荐