HttpServletRequestWrapper和HttpServletResponseWrapper详解

时间:2025-03-20 11:10:46

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.实例

创建一个过滤器,实现request中参数自动由繁体字转为简体字,且相应内容由简体字转为繁体字。

package ;


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() {


    }
}