标签:
网站常使用GZIP压缩算法对网页内容进行压缩,然后传给浏览器,以减小数据传输量,提高响应速度。浏览器接收到GZIP压缩数据后会自动解压并正确显示。GZIP加速常用于解决网速慢的瓶颈。
压缩Filter中需要先判断客户浏览器时候支持GZip自动解压,如果支持,则进行GZIP压缩,否则不压缩。判断的依据是浏览器提供的Header信息,代码如下:
GZipFilter.java
1 ?package 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>
标签:
原文地址:http://www.cnblogs.com/zfy0098/p/5566562.html