全站壓縮

我們要用到過濾器和GZIPOutputStream

思路:我們從servlet輸出到瀏覽器需要通過response調用getOutputsteam()或者getWriter()方法來進行輸出那麼我們就要先對response進行封裝,將它裏面的這兩個方法的返回類型換成ByteArrayOutputStream,將壓縮操作放到內存中來執行

然後通過過濾器放行,從服務器返回的結果應該再通過過濾器攔截,把獲得到的ByteArrayOutputStream數據通過GZIPOutputStream 進行壓縮,然後在過濾器自行調用新的response進行輸出

package cn.hncu.servlet;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.util.zip.GZIPOutputStream;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class gzipFilter implements Filter {

    @Override
    public void destroy() {

    }

    /*
     * 將字符型數據和字節型數據壓縮的結合
     */
    @Override
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        // 放行前,增強response,給它配置一個bout容器,同時攔截response.getoutputstream().write();
        // 讓write()方法寫入bout中
        MyResponse resp = new MyResponse((HttpServletResponse) response);
        chain.doFilter(request, resp);// 用增強版的response放行

        // 放行後,從增強版的resp中把bout取出來,進行壓縮,再用原裝response發向客戶端
        ByteArrayOutputStream bout = resp.getBout();
        byte srcDatas[] = bout.toByteArray();
        System.out.println(srcDatas.length);
        ByteArrayOutputStream bout2 = new ByteArrayOutputStream();
        GZIPOutputStream gzip = new GZIPOutputStream(bout2);
        gzip.write(srcDatas);
        gzip.close();
        byte destDatas[] = bout2.toByteArray();
        System.out.println(destDatas.length);
        ((HttpServletResponse) response).setHeader("Content-Encoding", "gzip");// 告訴瀏覽器要用gzip方式打開我們發的數據
        response.getOutputStream().write(destDatas);
    }

    @Override
    public void init(FilterConfig config) throws ServletException {

    }

    class MyResponse extends HttpServletResponseWrapper {
        private PrintWriter pw = null;
        private ByteArrayOutputStream bout = new ByteArrayOutputStream();

        public ByteArrayOutputStream getBout() {
            if (pw != null) {
                pw.close();
            }
            return bout;
        }

        public MyResponse(HttpServletResponse response) {
            super(response);
        }

        @Override
        public ServletOutputStream getOutputStream() throws IOException {
            return new MyoutputStream(bout);
        }

        @Override
        public PrintWriter getWriter() throws IOException {
            pw = new PrintWriter(new OutputStreamWriter(bout, "utf-8"), true);
            return pw;
        }
    }

    class MyoutputStream extends ServletOutputStream {
        private ByteArrayOutputStream bout;

        public MyoutputStream(ByteArrayOutputStream out) {
            this.bout = out;
        }

        @Override
        public void write(int arg0) throws IOException {
            bout.write(arg0);

        }

    }
}
發佈了105 篇原創文章 · 獲贊 10 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章