程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> JSP編程 >> 關於JSP >> [Servlet&JSP] 封裝器的使用

[Servlet&JSP] 封裝器的使用

編輯:關於JSP

[Servlet&JSP] 封裝器的使用


過濾器可以在執行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 escapeMap;

    public CharacterRequestWrapper(HttpServletRequest request, 
            Map 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 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 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();
            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中,響應就會是壓縮過後的內容。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved