2.HttpServletResponseWrapper
可以在response输出页面内容之前,进行页面内容的过滤等操作。
比如知名的页面装饰框架sitemesh,就是利用filter过滤器先截获返回给客户端的页面,然后分析html代码并最终装饰页面效果后返回给客户端。
类图:
由上图可见,HttpServletResponseWrapper是HttpServletResponse的实现类,所以HttpServletResponseWrapper可以替换HttpServletResponse。
同ServletResponseWrapper一样,ServletResponseWrapper也是采去了适配器模式,内部操作的也是构造方法中传递的ServletResponse。
此处我们创建一个可以获取到response中的输出流数据的HttpServletResponseWrapper:
package ;
import ;
import ;
import ;
import .*;
/**
* 定义response包装器ResponseWapper
* 用以获取response中的数据
* Created by Skyline on 2015/5/13.
*/
public class ResponseWapper extends HttpServletResponseWrapper {
private ByteArrayOutputStream buffer = null;
private ServletOutputStream out = null;
private PrintWriter writer = null;
public ResponseWapper(HttpServletResponse resp) throws IOException {
super(resp);
/**
* 替换默认的输出端,作为response输出数据的存储空间(即真正存储数据的流)
*/
buffer = new ByteArrayOutputStream();
/**
* response输出数据时是调用getOutputStream()和getWriter()方法获取输出流,再将数据输出到输出流对应的输出端的。
* 此处指定getOutputStream()和getWriter()返回的输出流的输出端为buffer,即将数据保存到buffer中。
*/
out = new WapperedOutputStream(buffer);
writer = new PrintWriter(new OutputStreamWriter(buffer, ()));
}
//重载父类获取outputstream的方法
@Override
public ServletOutputStream getOutputStream() throws IOException {
return out;
}
//重载父类获取writer的方法
@Override
public PrintWriter getWriter() throws UnsupportedEncodingException {
return writer;
}
/**
* 这是将数据输出的最后步骤
* @throws IOException
*/
@Override
public void flushBuffer() throws IOException {
if (out != null) {
();
}
if (writer != null) {
();
}
}
@Override
public void reset() {
();
}
public byte[] getResponseData() throws IOException {
flushBuffer();//将out、writer中的数据强制输出到WapperedResponse的buffer里面,否则取不到数据
return ();
}
//内部类,对ServletOutputStream进行包装,指定输出流的输出端
private class WapperedOutputStream extends ServletOutputStream {
private ByteArrayOutputStream bos = null;
public WapperedOutputStream(ByteArrayOutputStream stream) throws IOException {
bos = stream;
}
//将指定字节写入输出流bos
@Override
public void write(int b) throws IOException {
(b);
}
}
}
3.实例
import ;
import ;
import .*;
import ;
import ;
import ;
/**
* 语言过滤器
* 当需要时,将简体转为繁体
* Created by Skyline on 2015/5/13.
*/
public class LanguangeFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest)request;
if(ConfDomain.isFt_cn()) {
//自动将繁体参数转为简体参数的request包装器
// FtToJtRequestWrapper requestWrapper = new FtToJtRequestWrapper(httpServletRequest);
if(!isAjaxRequest(httpServletRequest)) {
// (requestWrapper, response);
(request, response);
} else {
//可以获取response中数据的response包装器
ResponseWapper wapper=new ResponseWapper((HttpServletResponse)response);
// (requestWrapper, wapper);
(request, wapper);
//获取response中的数据,并处理
byte[] resp_old = ();
String resp_old_str = new String(resp_old, ());
String resp_new_str = (resp_old_str);
byte[] resp_new = resp_new_str.getBytes(());
//输出处理后的数据,注意要用response而非wapper
ServletOutputStream output=();
(resp_new);
();
}
} else {
(request,response);
}
}
private boolean isAjaxRequest(HttpServletRequest request) {
return "XMLHttpRequest".equalsIgnoreCase(("X-Requested-With"));
}
@Override
public void destroy() {
}
}