有时我们希望在请求输出之前对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
上面是我们对HttpServletResponseWrapper的包装。随后我们可以编写自已一Filter来完成实现的工作。
这样在页面上调用后将会输出我们修改后的结果如上例为:jack
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
有时我们希望在请求输出之前对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
上面是我们对HttpServletResponseWrapper的包装。随后我们可以编写自已一Filter来完成实现的工作。
这样在页面上调用后将会输出我们修改后的结果如上例为:jack
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