使用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>

GZIP压缩优化的更多相关文章

  1. 针对ASP.NET页面实时进行GZIP压缩优化的几款压缩模块的使用简介及应用测试!(附源码)

    在介绍之前,先简单说一说ASP.NET服务端GZIP压缩模块的作用及工作原理,很多人编写网页的时候页面因为使用了大量的JS特效又或者放置很多大型动态广告导致了页面或脚本体积庞大,通常都会使用一些压缩工 ...

  2. Gzip压缩优化网站

    网站常使用GZIP压缩算法对网页内容进行压缩,然后传给浏览器,以减小数据传输量,提高响应速度.浏览器接收到GZIP压缩数据后会自动解压并正确显示.GZIP加速常用于解决网速慢的瓶颈. 压缩Filter ...

  3. 2017年05月10日记一次微项目投产 | 安卓版微信内置浏览器不能解析gzip压缩过的mp4视频的问题

    前言 今天投产了一个小项目,一个很简单的H5,有播放视频功能,使用了videojs插件. 之前也做过数个视频播放,视频的转压都按照既定流程进行,文件放到FTP后,iphone和安卓机测试下来都没有问题 ...

  4. 网站启用GZip压缩后,速度快了3倍!

    GZip压缩,是一种网站速度优化技术,也是一把SEO优化利器,许多网站都采用了这种技术,以达到提升网页打开速度.缩短网页打开时间的目的. 本文是一篇研究性文章,将通过某个案例来给大家显示网站采用GZi ...

  5. ASP.NET MVC 3 网站优化总结(一) 使用 Gzip 压缩

    网站开启 Gzip 压缩的好处相信很多人都已经清楚,这样做可以提高网站的性能.那么为什么很多网站没有开启 Gzip 压缩功能呢?原因有4点:防病毒软件.浏览器 bug.网站代理和服务器未配置. 使用 ...

  6. Nginx性能优化功能- Gzip压缩(大幅度提高页面加载速度)

    Nginx开启Gzip压缩功能, 可以使网站的css.js .xml.html 文件在传输时进行压缩,提高访问速度, 进而优化Nginx性能!  Web网站上的图片,视频等其它多媒体文件以及大文件,因 ...

  7. Tomcat性能优化之(一) 启动GZIP压缩

    Tomcat性能优化之(一) 启动GZIP压缩 1:设置TOMCAT启用GZIP压缩,通过浏览器HTTP访问对应的资源会根据配置进行压缩. <Connector port="8080& ...

  8. web性能优化之GZIP压缩

    从服务端优化来说,通过对服务端做压缩配置可以大大减小文本文件的体积,从而使加载文本的速度成倍的加快.目前比较通用的压缩方法是启用gzip压缩.它会把浏览器请求的页面,以及页面中引用的静态资源以压缩包的 ...

  9. 网站访问优化(二):开启apache服务器gzip压缩

    昨天,把带宽从1M升级到2M,使用cdn版本的jquery之后,网站访问速度由平均5s(在禁止缓存的情况下,使用缓存大概在2.8s)下降到2.8s的样子. 今天,继续优化. 第1步:   把图片进行了 ...

随机推荐

  1. Leetcode Divide Two Integers

    Divide two integers without using multiplication, division and mod operator. 不用乘.除.求余操作,返回两整数相除的结果,结 ...

  2. cookie小析

    cookie用于存储数据,当用户访问了某个网站(网页)时,我们就可以通过cookie来向访问者电脑上存储数据1.不同的浏览器存放的cookie位置不同,也不能通用2.cookie的存储是以域名的形式进 ...

  3. python中文注释报错问题

    错误信息: SyntaxError: Non-ASCII character '\xe4' in file... 解决办法: 在文件第一行或第二行添加:# -*- coding: utf-8 -*- ...

  4. UI控件闪烁及刷新

    我们常常在一个窗口上放置很多控件,在改变窗口大小时,控件会跟着一起闪烁... 此时,可以将窗口添加WS_CLIPCHILDREN属性即可.(如果包含多层,都需要WS_CLIPCHILDREN属性) 默 ...

  5. Thinking in Java——笔记(16)

    Arrays Why arrays are special There are three issues that distinguish arrays from other types of con ...

  6. 掌握Thinkphp3.2.0----CURD

    TP-----CURD  create()创建数据----整理数据 在数据库添加等操作之前,我们首先需要对数据进行创建.何为数据创建,就是接受提交过来的数据,比如表单提交的 POST(默认)数据.接受 ...

  7. 关于AFNetworking中header的bug问题

    关于AFNetworking中header的bug问题 [摘要:AFNetworking那个正在ios开辟中便未几道了,网上一搜一大推,然则详细用法我便没有道了,偶然间我会整顿一下详细的一些用法.本日 ...

  8. MySQL 表分区详解MyiSam引擎和InnoDb 区别(实测)

    一.什么是表分区通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysql5.1开始支持数据表分区了.如:某用户表的记录超过了1000万条,那么就可以根据入库日期将表分区,也可以根据所在地将表分区 ...

  9. scala中的数组的转换操作

    1.共有两种操作 转换成一种新的数组 2.yield转换 3.函数式编程转换

  10. C# 日期格式转【转】

    使用:DateTime.ToString的方法(String, IFormatProvider)转换格式 using System; using System.Globalization; Strin ...