• GZIP压缩优化


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

    相关知识:

      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 对象 

    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>   

  • 相关阅读:
    内存溢出和内存泄漏的区别
    测试管理三要素(人员、过程和技术)
    面试可提问的6个问题
    弱网测试(二)
    js捕获错误
    TortoiseGit自动记住用户名密码的方法
    win7 "com surrogate“ 已停止工作的解决办法
    仿百度图片毛玻璃效果
    毛玻璃效果
    vimium快捷键列表
  • 原文地址:https://www.cnblogs.com/Coolkaka/p/5962797.html
Copyright © 2020-2023  润新知