[Servlet&JSP] 封装器的使用

来源:互联网 发布:js 二维数组初始化为0 编辑:程序博客网 时间:2024/06/08 01:54

过滤器可以在执行Servlet的service()方法前后,进行前置和后置处理。但是有些信息无法更改,例如请求参数。使用请求封装器及相应封装器,将容器产生的请求与相应对象加以封装,可以针对某个请求信息或响应进行加工处理。

请求封装器

HttpServletRequestWrapper实现了HttpServletRequest接口,以下范例通过继承HttpServletRequestWrapper实现了一个请求封装器,可以请请求参数中的角括号替换为替代字符。

import java.util.Iterator;import java.util.Map;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletRequestWrapper;public class CharacterRequestWrapper extends HttpServletRequestWrapper{    private Map<String, String> escapeMap;    public CharacterRequestWrapper(HttpServletRequest request,             Map<String, String> escapeMap) {        super(request); //封装传入的请求对象        this.escapeMap = escapeMap;    }    @Override    public String getParameter(String name) { //重写getParameter()方法        return doEscape(this.getRequest().getParameter(name));    }    private String doEscape(String parameter) {        if (parameter == null) {            return null;        }        String result = parameter;        Iterator<String> it = escapeMap.keySet().iterator();        while(it.hasNext()) {            String origin = it.next();            String escape = escapeMap.get(origin);            result = result.replaceAll(origin, escape);        }        return result;    }}

可以使用这个请求封装器搭配过滤器,以进行字符过滤的服务。例如:

import java.io.BufferedReader;import java.io.IOException;import java.io.InputStreamReader;import java.util.HashMap;import java.util.Map;import java.util.logging.Level;import java.util.logging.Logger;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;public class CharacterFilter implements Filter {    private Map<String, String> escapeMap;    @Override    public void init(FilterConfig filterConfig) throws ServletException {        BufferedReader reader = null;        try {            String escapeListFile = filterConfig.getInitParameter("ESCAPE_LIST");            reader = new BufferedReader(new InputStreamReader(                    filterConfig.getServletContext().getResourceAsStream(escapeListFile)));            String input = null;            escapeMap = new HashMap<String, String>();            while ((input = reader.readLine()) != null) {                String[] token = input.split("\t");                escapeMap.put(token[0], token[1]);            }        } catch (IOException ex) {            Logger.getLogger(CharacterFilter.class.getName())                    .log(Level.SEVERE, null, ex);        } finally {            try {                reader.close();            } catch (IOException ex) {                Logger.getLogger(CharacterFilter.class.getName())                        .log(Level.SEVERE, null, ex);            }        }    }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)            throws IOException, ServletException {        //将原请求对象封装到CharacterRequestWrapper中        HttpServletRequest requestWrapper =                 new CharacterRequestWrapper((HttpServletRequest)request, escapeMap);        //将CharacterRequestWrapper对象当做请求参数传入doFilter()        chain.doFilter(requestWrapper, response);    }    @Override    public void destroy() {        // TODO Auto-generated method stub    }}

响应封装器

如果想要对响应的内容进行压缩处理等,可以在响应封装器部分继承HttpServletResponseWrapper类来对HttpServletResponse对象进行封装。

如要对浏览器进行输出响应,必须通过getWriter()取得PrintWriter,或是通过getOutputStream()取得ServletOutputStream。所以针对压缩输出的请求,主要就是继承HttpServletResponseWrapper之后,通过重写这两个方法来达成的。

在这里压缩功能将采用GZIP格式,这是浏览器可以接受的压缩格式,可以使用GZIPOutputStream类来实现。由于getWriter()的PrintWriter在创建时也是必须要用到ServletOutputStream,所以这里首先扩展ServletOutputStream类,让它具有压缩功能。

GzipServletOutputStream.java:

package club.chuxing;import java.io.IOException;import java.util.zip.GZIPOutputStream;import javax.servlet.ServletOutputStream;import javax.servlet.WriteListener;public class GZipServletOutputStream extends ServletOutputStream{    private GZIPOutputStream gzipOutputStream;    public GZipServletOutputStream(ServletOutputStream servletOutputStream)             throws IOException {        this.gzipOutputStream = new GZIPOutputStream(servletOutputStream);    }    public void write(int b) throws IOException {        //输出时通过GZIPOutputSteam的write()压缩输出        gzipOutputStream.write(b);    }    public GZIPOutputStream getGzipOutputStream() {        return gzipOutputStream;    }    @Override    public boolean isReady() {        // TODO Auto-generated method stub        return false;    }    @Override    public void setWriteListener(WriteListener listener) {        // TODO Auto-generated method stub    }}

CompressionResponseWrapper.java:

package club.chuxing;import java.io.IOException;import java.io.OutputStreamWriter;import java.io.PrintWriter;import java.util.zip.GZIPOutputStream;import javax.servlet.ServletOutputStream;import javax.servlet.http.HttpServletResponse;import javax.servlet.http.HttpServletResponseWrapper;public class CompressionResponseWrapper extends HttpServletResponseWrapper {    private GZipServletOutputStream gzServletOutputStream;    private PrintWriter printWriter;    public CompressionResponseWrapper(HttpServletResponse resp) {        super(resp);    }    @Override    public ServletOutputStream getOutputStream() throws IOException {        if (printWriter != null) {            throw new IllegalStateException();        }        if (gzServletOutputStream == null) {            gzServletOutputStream = new GZipServletOutputStream(                    getResponse().getOutputStream());        }        return gzServletOutputStream;    }    @Override    public PrintWriter getWriter() throws IOException {        if (gzServletOutputStream != null) {            throw new IllegalStateException();        }        if (printWriter == null) {            gzServletOutputStream = new GZipServletOutputStream(                    getResponse().getOutputStream());            OutputStreamWriter osw = new OutputStreamWriter(                    gzServletOutputStream, getResponse().getCharacterEncoding());            printWriter = new PrintWriter(osw);        }        return printWriter;    }    @Override    public void setContentLength(int len) {    }    public GZIPOutputStream getGZIPOutputStream() {        if (this.gzServletOutputStream == null) {            return null;        }        return this.gzServletOutputStream.getGzipOutputStream();    }}

CompressionFilter.java(压缩过滤器):

package club.chuxing;import java.io.IOException;import java.util.zip.GZIPOutputStream;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;public class CompressionFilter implements Filter {    @Override    public void init(FilterConfig filterConfig) throws ServletException {        // TODO Auto-generated method stub    }    @Override    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)            throws IOException, ServletException {        HttpServletRequest req = (HttpServletRequest)request;        HttpServletResponse res = (HttpServletResponse)response;        String encodings = req.getHeader("accept-encoding");        if ((encodings != null) && encodings.indexOf("gzip") > -1) {            //建立响应封装            CompressionResponseWrapper responseWrapper =                     new CompressionResponseWrapper(res);            //设置响应内容编码为gzip格式            responseWrapper.setHeader("content-encoding", "gzip");            chain.doFilter(request, responseWrapper);            GZIPOutputStream gzipOutputStream = responseWrapper.getGZIPOutputStream();            if (gzipOutputStream != null) {                //调用GZIPOutputStream的finish()方法完成压缩输出                gzipOutputStream.finish();            }        } else {            chain.doFilter(request, response);        }    }    @Override    public void destroy() {        // TODO Auto-generated method stub    }}

最后,将过滤器设置在web.xml中,响应就会是压缩过后的内容。

0 0
原创粉丝点击