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

本文介绍如何通过继承HttpServletResponseWrapper来自定义HTTP响应,实现对响应输出的处理与持久化。通过创建WrapperedResponse类并重写关键方法,可以将输出保存在自定义流中,以便进一步操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

有时我们希望在请求输出之前对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 
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值