使用gzip優化web應用(filter實現)

實      現:   javascript

Tomcat 開啓Gzipcss

1.找到Tomcat 目錄下的conf下的server.xml,並找到以下信息 html

Connector port = "8080" maxHttpHeaderSize = "8192" maxThreads = "150" minSpareThreads = "25" maxSpareThreads = "75" enableLookups = "false" redirectPort = "8443" acceptCount = "100" connectionTimeout = "20000" disableUploadTimeout = "true"

將它改爲以下的形式(其實在上面代碼的下面已經有了,將他們打開而已。): java

<!-- Define a non-SSL HTTP/1.1 Connector on port 8080 --> <Connector port="8080" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" compression="on" compressionMinSize="2048" noCompressionUserAgents="gozilla, traviata" compressableMimeType="text/html,text/xml" >

這樣,就可以對html和xml進行壓縮了,若是要壓縮css 和 js,那麼須要將 web

compressableMimeType=」text/html,text/xml」加入css和js: 瀏覽器

<Connector port="8080" ......... compressableMimeType="text/html,text/xml,text/css,text/javascript" >

你甚至能夠壓縮圖片: 服務器

compressableMimeType=」text/html,text/xml」加入css和js: app

<Connector port="8080" ......... compressableMimeType="text/html,text/xml,text/css,text/javascript,image/gif,image/jpg" >

開啓後重啓Tomcat ,經過瀏覽器查看headers信息就能看到是否開啓(firebug中有),若是開啓了,那麼transfer-encoding就會是Gzip,不然就是chunked。 ide

 

在代碼級別完成web應用的gzip壓縮的開啓: this

 

1.Wrapper  用來包裝HttpServletResponse 對象 

Java代碼

package com.shop.gzip;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;

public class Wrapper extends HttpServletResponseWrapper {
    public static final int OT_NONE = 0, OT_WRITER = 1, OT_STREAM = 2;
    private int outputType = OT_NONE;
    private ServletOutputStream output = null;
    private PrintWriter writer = null;
    private ByteArrayOutputStream buffer = null;

    public Wrapper(HttpServletResponse resp) throws IOException {
        super(resp);
        buffer = new ByteArrayOutputStream();
    }

    public PrintWriter getWriter() throws IOException {
        if (outputType == OT_STREAM)
            throw new IllegalStateException();
        else if (outputType == OT_WRITER)
            return writer;
        else {
            outputType = OT_WRITER;
            writer = new PrintWriter(new OutputStreamWriter(buffer,
                    getCharacterEncoding()));
            return writer;
        }
    }

    public ServletOutputStream getOutputStream() throws IOException {
        if (outputType == OT_WRITER)
            throw new IllegalStateException();
        else if (outputType == OT_STREAM)
            return output;
        else {
            outputType = OT_STREAM;
            output = new WrappedOutputStream(buffer);
            return output;
        }
    }

    public void flushBuffer() throws IOException {
        if (outputType == OT_WRITER)
            writer.flush();
        if (outputType == OT_STREAM)
            output.flush();
    }

    public void reset() {
        outputType = OT_NONE;
        buffer.reset();
    }

    public byte[] getResponseData() throws IOException {
        flushBuffer();
        return buffer.toByteArray();

    }

    class WrappedOutputStream extends ServletOutputStream {
        private ByteArrayOutputStream buffer;

        public WrappedOutputStream(ByteArrayOutputStream buffer) {
            this.buffer = buffer;
        }

        public void write(int b) throws IOException {
            buffer.write(b);
        }

        public byte[] toByteArray() {
            return buffer.toByteArray();
        }
    }
}

 

 

2.過濾器

 

Java代碼

 

 package com.shop.gzip;

import java.io.ByteArrayOutputStream;
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.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class GZipFilter implements Filter {

    public void destroy() {
    }
      /**
       * 判斷瀏覽器是否支持GZIP
       * @param request
       * @return
       */
      private static boolean isGZipEncoding(HttpServletRequest request){
        boolean flag=false;
        String encoding=request.getHeader("Accept-Encoding");
        if(encoding.indexOf("gzip")!=-1){
          flag=true;
        }
        return flag;
      }
      
    public void doFilter(ServletRequest request, ServletResponse response,
            FilterChain chain) throws IOException, ServletException {
        HttpServletResponse resp = (HttpServletResponse) response;
        HttpServletRequest req=(HttpServletRequest)request;
        if(isGZipEncoding(req)){
            Wrapper wrapper = new Wrapper(resp);
            chain.doFilter(request, wrapper);
            byte[] gzipData = gzip(wrapper.getResponseData());
            resp.addHeader("Content-Encoding", "gzip");
            resp.setContentLength(gzipData.length);
            ServletOutputStream output = response.getOutputStream();
            output.write(gzipData);
            output.flush();
        } else {
            chain.doFilter(request, response);
        }        

    }

    public void init(FilterConfig arg0) throws ServletException {

    }

    private byte[] gzip(byte[] data) {
        ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(10240);
        GZIPOutputStream output = null;
        try {
            output = new GZIPOutputStream(byteOutput);
            output.write(data);
        } catch (IOException e) {
        } finally {
            try {
                output.close();
            } catch (IOException e) {
            }
        }
        return byteOutput.toByteArray();
    }

}

3.在web.xml中配置 GZipFilter,當咱們訪問應用中以.do結尾的資源的使用,服務器端就開啓http gzip壓縮,將壓縮後的信息經過http 協議傳遞給瀏覽器.  

  

Xml代碼

<filter>  

  <filter-name>ecsideExport</filter-name>  

  <filter-class>com.web.servlet.GZipFilter</filter-class>  

 </filter>  

<filter-mapping>  

             <filter-name>ecsideExport</filter-name>  

            <url-pattern>*.do</url-pattern>  

</filter-mapping>

相關文章
相關標籤/搜索