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

16 篇文章 0 订阅
1 篇文章 0 订阅
有时我们希望在请求输出之前对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 

public class WrapperedResponse extends HttpServletResponseWrapper { 

private ByteArrayOutputStream buffer = null; 
private ServletOutputStream out = null; 
private PrintWriter writer = null; 

public WrapperedResponse(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(); 
} 

/**将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据*/ 
public byte[] getResponseData() throws IOException { 
flushBuffer(); 
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); 
} 
@Override 
public void write(byte[] b) throws IOException { 
bos.write(b, 0, b.length); 
} 
} 
} 



上面是我们对HttpServletResponseWrapper的包装。随后我们可以编写自已一Filter来完成实现的工作。 
@Override 
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { 

log.info("begin filter invoke!"); 
WrapperedResponse wrapResponse = new WrapperedResponse((HttpServletResponse)response); 

chain.doFilter(request, wrapResponse); 
byte[] data = wrapResponse.getResponseData(); 
log.info("原始数据: " + new String(data)); 


String tempData = new String("jack"); 
ServletOutputStream out = response.getOutputStream(); 
out.write(tempData.getBytes()); 
out.flush(); 

log.info("end filter invoke!"); 
} 


这样在页面上调用后将会输出我们修改后的结果如上例为:jack  
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值