`

使用gzip优化web应用(filter实现)

    博客分类:
  • Java
 
阅读更多

使用gzip优化web应用(filter实现) http://john-kong19.iteye.com/blog/1038941
tomcat如何使用Gzip对静态文件压缩 2 http://panyongzheng.iteye.com/blog/2249815


tomcat如何使用Gzip对静态文件压缩  1 http://www.wuji8.com/meta/568440954.html


配置Apache,Tomcat的gzip压缩功能 http://kangyang.blog.51cto.com/471772/580883
关于JavaScript的gzip静态压缩方法 http://badqiu.iteye.com/blog/37176


相关知识:

  gzip是http协议中使用的一种加密算法,客户端向web服务器端发出了请求后,通常情况下服务器端会将页面文件和其他资源,返回到客户端,客户端加载后渲染呈现,这种情况文件一般都比较大,如果开启Gzip ,那么服务器端响应后,会将页面,JS,CSS等文本文件或者其他文件通过高压缩算法将其压缩,然后传输到客户端,由客户端的浏览器负责解压缩与呈现。通常能节省40%以上的流量(一般都有60%左右),一些PHP,JSP文件也能够进行压缩。

实      现:  

Tomcat 开启Gzip :

1.找到Tomcat 目录下的conf下的server.xml,并找到如下信息
Connector port="8080" maxHttpHeaderSize="8192" maxThreads="150" minSpareThreads="25" maxSpareThreads="75" enableLookups="false" redirectPort="8443" acceptCount="100" connectionTimeout="20000" disableUploadTimeout="true" 

将它改成如下的形式(其实在上面代码的下面已经有了,将他们打开而已。):
<!-- 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,那么需要将

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:

<Connector port="8080" ......... compressableMimeType="text/html,text/xml,text/css,text/javascript,image/gif,image/jpg" >
开启后重启Tomcat ,通过浏览器查看headers信息就能看到是否开启(firebug中有),如果开启了,那么transfer-encoding就会是Gzip,否则就是chunked。



在代码级别完成web应用的gzip压缩的开启:
1.Wrapper  用来包装HttpServletResponse 对象
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;

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();
        }
    }
} 



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.过滤器
public class GZipFilter implements Filter 
{ 

public void destroy() 
{ 
  // TODO Auto-generated method stub 
  
} 

public void doFilter(ServletRequest request, ServletResponse response, 
   FilterChain chain) throws IOException, ServletException 
   { 
   System.out.println("进入过滤器"); 
   HttpServletResponse resp = (HttpServletResponse)response; 
   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(); 
   } 

public void init(FilterConfig arg0) throws ServletException 
{ 
  // TODO Auto-generated method stub 
  
} 

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(); 
  } 

} 



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 协议传递给浏览器. 
<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>  
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics