ITPub博客

首页 > 应用开发 > Java > 使用gzip优化web应用(filter实现)

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

Java 作者:破棉袄 时间:2014-07-16 13:30:28 0 删除 编辑

 以前使用过filter,也就是屏蔽一下受限制的资源访问路径,解决下中文乱码问题,其实filter在优化web应用发面也有出色的应用,我们可以使用filter,结合gzip 压缩技术,解决web应用中网络传输数据量大的问题,一般使用了gzip压缩,网络的传输流量能减少40%作用,效果还是相当明显的.在工作中,gzip在企业级的应用中还不是很普遍,也许是程序员一开始想的就是sql优化,缓存等更直接有效的方式,而忽略了gzip压缩方法吧.

 

    

为什么要开启Gzip ?

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

		

这样,就能够对html和xml进行压缩了,如果要压缩css 和 js,那么需要将

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


		

你甚至可以压缩图片:

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


		

 

——开启后——–

开启后重启Tomcat ,通过浏览器查看headers信息就能看到是否开启(firebug中有),如果开启了,那么transfer-encoding就会是Gzip,否则就是chunked。

 

  以上方式依赖了tomcat服务器的特性,如果你服务器是iis或者websphere那么还有不同的配置方式,下面我们使用filter,在代码级别完成web应用的gzip压缩的开启.

 

   实现定制输出的关键是对HttpServletResponse 进行包装,截获所有的输出,等到过滤器链处理完毕后,再对截获的输出进行处理,并写入到真正的HttpServletResponse 对象中。JavaEE 框架已经定义了一个HttpServletResponseWrapper 类使得包装HttpServletResponse 更加容易。我们扩展这个HttpServletResponseWrapper,截获所有的输出,并保存到ByteArrayOutputStream 中

 

步骤:

 

 

 

1.Wrapper  用来包装HttpServletResponse 对象

 

 

Java代码 复制代码 收藏代码
  1. public class Wrapper extends HttpServletResponseWrapper  
  2. {  
  3.     public static final int OT_NONE = 0, OT_WRITER = 1, OT_STREAM = 2;  
  4.     private int outputType = OT_NONE;  
  5.     private ServletOutputStream output = null;  
  6.     private PrintWriter writer = null;  
  7.     private ByteArrayOutputStream buffer = null;  
  8.     public Wrapper(HttpServletResponse resp) throws IOException {  
  9.     super(resp);  
  10.     buffer = new ByteArrayOutputStream();  
  11.     }  
  12.     public PrintWriter getWriter() throws IOException {  
  13.     if(outputType==OT_STREAM)  
  14.     throw new IllegalStateException();  
  15.     else if(outputType==OT_WRITER)  
  16.     return writer;  
  17.     else {  
  18.     outputType = OT_WRITER;  
  19.     writer = new PrintWriter(new OutputStreamWriter(buffer, getCharacterEncoding()));  
  20.     return writer;  
  21.     }  
  22.     }  
  23.     public ServletOutputStream getOutputStream() throws IOException {  
  24.     if(outputType==OT_WRITER)  
  25.     throw new IllegalStateException();  
  26.     else if(outputType==OT_STREAM)  
  27.     return output;  
  28.     else {  
  29.     outputType = OT_STREAM;  
  30.     output = new WrappedOutputStream(buffer);  
  31.     return output;  
  32.     }  
  33.     }  
  34.     public void flushBuffer() throws IOException {  
  35.     if(outputType==OT_WRITER)  
  36.     writer.flush();  
  37.     if(outputType==OT_STREAM)  
  38.     output.flush();  
  39.     }  
  40.     public void reset() {  
  41.     outputType = OT_NONE;  
  42.     buffer.reset();  
  43.     }  
  44.     public byte[] getResponseData() throws IOException {  
  45.     flushBuffer();  
  46.     return buffer.toByteArray();  
  47.   
  48.     }  
  49.     class WrappedOutputStream extends ServletOutputStream {  
  50.     private ByteArrayOutputStream buffer;  
  51.     public WrappedOutputStream(ByteArrayOutputStream buffer) {  
  52.     this.buffer = buffer;  
  53.     }  
  54.     public void write(int b) throws IOException {  
  55.     buffer.write(b);  
  56.     }  
  57.     public byte[] toByteArray() {  
  58.     return buffer.toByteArray();  
  59.     }  
  60.     }  
  61. }  

 

 

 

2.过滤器

 

Java代码 复制代码 收藏代码
  1. public class GZipFilter implements Filter  
  2. {  
  3.   
  4.     public void destroy()  
  5.     {  
  6.         // TODO Auto-generated method stub  
  7.           
  8.     }  
  9.   
  10.     public void doFilter(ServletRequest request, ServletResponse response,  
  11.             FilterChain chain) throws IOException, ServletException   
  12.             {  
  13.             System.out.println("进入过滤器");  
  14.             HttpServletResponse resp = (HttpServletResponse)response;  
  15.             Wrapper wrapper = new Wrapper(resp);  
  16.             chain.doFilter(request, wrapper);  
  17.             byte[] gzipData = gzip(wrapper.getResponseData());  
  18.             resp.addHeader("Content-Encoding", "gzip");  
  19.             resp.setContentLength(gzipData.length);  
  20.             ServletOutputStream output = response.getOutputStream();  
  21.             output.write(gzipData);  
  22.             output.flush();  
  23.             }  
  24.   
  25.     public void init(FilterConfig arg0) throws ServletException  
  26.     {  
  27.         // TODO Auto-generated method stub  
  28.           
  29.     }  
  30.   
  31.     private byte[] gzip(byte[] data) {  
  32.         ByteArrayOutputStream byteOutput = new ByteArrayOutputStream(10240);  
  33.         GZIPOutputStream output = null;  
  34.         try {  
  35.         output = new GZIPOutputStream(byteOutput);  
  36.         output.write(data);  
  37.         }  
  38.         catch (IOException e) {}  
  39.         finally {  
  40.         try {  
  41.         output.close();  
  42.         }  
  43.         catch (IOException e) {}  
  44.         }  
  45.         return byteOutput.toByteArray();  
  46.         }  
  47.       
  48. }  

 

 

 

 


 

 3.在web.xml中配置 GZipFilter,当我们访问应用中以.html结尾的资源的使用,服务器端就开启http gzip压缩,将压缩后的信息通过http 协议传递给浏览器.

 

  

Xml代码 复制代码 收藏代码
  1. <filter>  
  2.         <filter-name>ecsideExportfilter-name>  
  3.         <filter-class>cn.com.xinli.test.GZipFilterfilter-class>  
  4.     filter>  
  5.  <filter-mapping>  
  6.              <filter-name>ecsideExportfilter-name>  
  7.              <url-pattern>*.htmlurl-pattern>  
  8.          filter-mapping>   
  9.       

 

 

测试: 首先下载ieHttpHeader 插件.

 

测试地址:

http://localhost:9090/dwr/test.html

 

   1.未开启http gzip 压缩

 

 GET /dwr/test.html HTTP/1.1
Accept: */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: localhost:9090
Connection: Keep-Alive


HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
ETag: W/"5060-1242444154000"
Last-Modified: Sat, 16 May 2009 03:22:34 GMT
Content-Type: text/html
Content-Length: 5060
Date: Mon, 18 May 2009 12:29:49 GMT

 

 

   2.开启http gzip 压缩

 

GET /dwr/test.html HTTP/1.1
Accept: image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, application/x-shockwave-flash, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, */*
Accept-Language: zh-cn
Accept-Encoding: gzip, deflate
User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1)
Host: localhost:9090
Connection: Keep-Alive

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
ETag: W/"5060-1242444154000"
Last-Modified: Sat, 16 May 2009 03:22:34 GMT
Content-Encoding: gzip
Content-Type: text/html
Content-Length: 837
Date: Mon, 18 May 2009 12:27:33 GMT

 

效果是非常明显的..........


    


 

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29754888/viewspace-1220264/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2014-07-16

  • 博文量
    180
  • 访问量
    1158151