Gzip压缩优化网站

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

压缩Filter中需要先判断客户浏览器时候支持GZip自动解压,如果支持,则进行GZIP压缩,否则不压缩。判断的依据是浏览器提供的Header信息,代码如下:

GZipFilter.java

 1package com.rom.util;
 2  
 3 import java.io.IOException;
 4  
 5 import javax.servlet.Filter;
 6 import javax.servlet.FilterChain;
 7 import javax.servlet.FilterConfig;
 8 import javax.servlet.ServletException;
 9 import javax.servlet.ServletRequest;
10 import javax.servlet.ServletResponse;
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse;
13  
14 /**
15  * Servlet Filter implementation class GzipFilter
16  */
17 public class GzipFilter implements Filter {
18  
19     /**
20      * Default constructor.
21      */
22     public GzipFilter() {
23         // TODO Auto-generated constructor stub
24     }
25  
26     /**
27      * @see Filter#destroy()
28      */
29     public void destroy() {
30         // TODO Auto-generated method stub
31     }
32  
33     /**
34      * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain)
35      */
36     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) {
37         // TODO Auto-generated method stub
38         // place your code here
39  
40         System.out.println("压缩的");
41  
42  
43         // TODO Auto-generated method stub 
44         HttpServletRequest request = (HttpServletRequest)req; 
45         HttpServletResponse response =(HttpServletResponse)res; 
46  
47         String acceptEncoding =request.getHeader("Accept-Encoding"); 
48         //支持的编码方式 
49  
50         try {
51             if(acceptEncoding != null && acceptEncoding.toLowerCase().indexOf("gzip") != -1){ 
52  
53                 System.out.println("执行压缩的方法");
54  
55                 //如果客户浏览器支持GZIP格式,则使用GZIP压缩数据 
56                 GZipResponseWrapper gzipRes = new GZipResponseWrapper(response); 
57  
58                 chain.doFilter(request, gzipRes);//doFilter,使用自定义的response 
59                 gzipRes.finishResponse();//输出压缩数据 
60  
61             }else{ 
62                 System.out.println("没有压缩");
63  
64                 chain.doFilter(request, response);//否则不压缩 
65             } 
66 //          chain.doFilter(request, response);
67         } catch (IOException e) {
68             e.printStackTrace();
69         } catch (ServletException e) {
70             e.printStackTrace();
71         }
72     }
73  
74     /**
75      * @see Filter#init(FilterConfig)
76      */
77     public void init(FilterConfig fConfig) throws ServletException {
78         // TODO Auto-generated method stub
79     }
80  
81 }

GZipResponseWrapper为自定义的response类,内部将对输出的内容进行GZIP压缩。它集成HttpServletResponseWrapper类,也是一个“伪装”的response,不真正输出内容到客户端。

GZipResponseWrapper.java

 1 package com.rom.util;
 2  
 3 import java.io.IOException;
 4 import java.io.OutputStreamWriter;
 5 import java.io.PrintWriter;
 6  
 7 import javax.servlet.ServletOutputStream;
 8 import javax.servlet.http.HttpServletResponse;
 9 import javax.servlet.http.HttpServletResponseWrapper;
10  
11 public class GZipResponseWrapper extends HttpServletResponseWrapper {
12      // 默认的 response 
13     private HttpServletResponse response; 
14  
15     // 自定义的 outputStream, 执行close()的时候对数据压缩,并输出 
16     private GZipOutputStream gzipOutputStream; 
17  
18     // 自定义 printWriter,将内容输出到 GZipOutputStream 中 
19     private PrintWriter writer; 
20  
21     public GZipResponseWrapper(HttpServletResponse response) throws IOException { 
22         super(response); 
23         this.response = response; 
24     } 
25  
26     public ServletOutputStream getOutputStream() throws IOException { 
27         if (gzipOutputStream == null) 
28             gzipOutputStream = new GZipOutputStream(response); 
29         return gzipOutputStream; 
30     } 
31  
32     public PrintWriter getWriter() throws IOException { 
33         if (writer == null) 
34             writer = new PrintWriter(new OutputStreamWriter( 
35                     new GZipOutputStream(response), "UTF-8")); 
36         return writer; 
37     } 
38  
39     // 压缩后数据长度会发生变化 因此将该方法内容置空 
40     public void setContentLength(int contentLength) { 
41     } 
42  
43     public void flushBuffer() throws IOException { 
44         gzipOutputStream.flush(); 
45     } 
46  
47     public void finishResponse() throws IOException { 
48         if (gzipOutputStream != null) 
49             gzipOutputStream.close(); 
50         if (writer != null) 
51             writer.close(); 
52     } 
53 }

getWriter()与getOutputStream()都使用了GZipOutputStream类。这是自定义的一个ServletOutputStream类,它先将数据缓存起来,然后使用JDK自带的GZIP压缩类将数据压缩,并输出到客户端浏览器。GZIP数据压缩与输出都在该类里实现的。

GZipOutputStream.java

 1 package com.rom.util;
 2  
 3 import java.io.ByteArrayOutputStream;
 4 import java.io.IOException;
 5 import java.util.zip.GZIPOutputStream;
 6  
 7 import javax.servlet.ServletOutputStream;
 8 import javax.servlet.http.HttpServletResponse;
 9  
10 public class GZipOutputStream extends ServletOutputStream {
11  
12      private HttpServletResponse response; 
13  
14  
15         private GZIPOutputStream gzipOutputStream; 
16  
17  
18         private ByteArrayOutputStream byteArrayOutputStream; 
19  
20         public GZipOutputStream(HttpServletResponse response) throws IOException { 
21             this.response = response; 
22             byteArrayOutputStream = new ByteArrayOutputStream(); 
23             gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream); 
24         } 
25  
26         public void write(int b) throws IOException { 
27             gzipOutputStream.write(b); 
28         } 
29  
30         public void close() throws IOException { 
31  
32  
33             gzipOutputStream.finish(); 
34  
35  
36             byte[] content = byteArrayOutputStream.toByteArray(); 
37  
38  
39             response.addHeader("Content-Encoding", "gzip"); 
40             response.addHeader("Content-Length", Integer.toString(content.length)); 
41  
42  
43             ServletOutputStream out = response.getOutputStream(); 
44             out.write(content); 
45             out.close(); 
46         } 
47  
48         public void flush() throws IOException { 
49             gzipOutputStream.flush(); 
50         } 
51  
52         public void write(byte[] b, int off, int len) throws IOException { 
53             gzipOutputStream.write(b, off, len); 
54         } 
55  
56         public void write(byte[] b) throws IOException { 
57             gzipOutputStream.write(b); 
58         } 
59  
60 }

添加xml配置文件

1  <filter>
2   <display-name>GzipFilter</display-name>
3   <filter-name>GzipFilter</filter-name>
4   <filter-class>com.rom.util.GzipFilter</filter-class>
5 </filter>
6 <filter-mapping>
7   <filter-name>GzipFilter</filter-name>
8   <url-pattern>/*</url-pattern>
9 </filter-mapping>

 

posted @ 2016-06-07 12:24  幸福流浪  阅读(438)  评论(0编辑  收藏  举报