Gzip压缩优化网站
2016-06-07 12:24
357 查看
网站常使用GZIP压缩算法对网页内容进行压缩,然后传给浏览器,以减小数据传输量,提高响应速度。浏览器接收到GZIP压缩数据后会自动解压并正确显示。GZIP加速常用于解决网速慢的瓶颈。
压缩Filter中需要先判断客户浏览器时候支持GZip自动解压,如果支持,则进行GZIP压缩,否则不压缩。判断的依据是浏览器提供的Header信息,代码如下:
GZipFilter.java
GZipResponseWrapper为自定义的response类,内部将对输出的内容进行GZIP压缩。它集成HttpServletResponseWrapper类,也是一个“伪装”的response,不真正输出内容到客户端。
GZipResponseWrapper.java
getWriter()与getOutputStream()都使用了GZipOutputStream类。这是自定义的一个ServletOutputStream类,它先将数据缓存起来,然后使用JDK自带的GZIP压缩类将数据压缩,并输出到客户端浏览器。GZIP数据压缩与输出都在该类里实现的。
GZipOutputStream.java
添加xml配置文件
压缩Filter中需要先判断客户浏览器时候支持GZip自动解压,如果支持,则进行GZIP压缩,否则不压缩。判断的依据是浏览器提供的Header信息,代码如下:
GZipFilter.java
package com.rom.util; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; /** * Servlet Filter implementation class GzipFilter */ public class GzipFilter implements Filter { /** * Default constructor. */ public GzipFilter() { // TODO Auto-generated constructor stub } /** * @see Filter#destroy() */ public void destroy() { // TODO Auto-generated method stub } /** * @see Filter#doFilter(ServletRequest, ServletResponse, FilterChain) */ public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) { // TODO Auto-generated method stub // place your code here System.out.println("压缩的"); // TODO Auto-generated method stub HttpServletRequest request = (HttpServletRequest)req; HttpServletResponse response =(HttpServletResponse)res; String acceptEncoding =request.getHeader("Accept-Encoding"); //支持的编码方式 try { if(acceptEncoding != null && acceptEncoding.toLowerCase().indexOf("gzip") != -1){ System.out.println("执行压缩的方法"); //如果客户浏览器支持GZIP格式,则使用GZIP压缩数据 GZipResponseWrapper gzipRes = new GZipResponseWrapper(response); chain.doFilter(request, gzipRes);//doFilter,使用自定义的response gzipRes.finishResponse();//输出压缩数据 }else{ System.out.println("没有压缩"); chain.doFilter(request, response);//否则不压缩 } // chain.doFilter(request, response); } catch (IOException e) { e.printStackTrace(); } catch (ServletException e) { e.printStackTrace(); } } /** * @see Filter#init(FilterConfig) */ public void init(FilterConfig fConfig) throws ServletException { // TODO Auto-generated method stub } }
GZipResponseWrapper为自定义的response类,内部将对输出的内容进行GZIP压缩。它集成HttpServletResponseWrapper类,也是一个“伪装”的response,不真正输出内容到客户端。
GZipResponseWrapper.java
package com.rom.util; 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 GZipResponseWrapper extends HttpServletResponseWrapper { // 默认的 response private HttpServletResponse response; // 自定义的 outputStream, 执行close()的时候对数据压缩,并输出 private GZipOutputStream gzipOutputStream; // 自定义 printWriter,将内容输出到 GZipOutputStream 中 private PrintWriter writer; public GZipResponseWrapper(HttpServletResponse response) throws IOException { super(response); this.response = response; } public ServletOutputStream getOutputStream() throws IOException { if (gzipOutputStream == null) gzipOutputStream = new GZipOutputStream(response); return gzipOutputStream; } public PrintWriter getWriter() throws IOException { if (writer == null) writer = new PrintWriter(new OutputStreamWriter( new GZipOutputStream(response), "UTF-8")); return writer; } // 压缩后数据长度会发生变化 因此将该方法内容置空 public void setContentLength(int contentLength) { } public void flushBuffer() throws IOException { gzipOutputStream.flush(); } public void finishResponse() throws IOException { if (gzipOutputStream != null) gzipOutputStream.close(); if (writer != null) writer.close(); } }
getWriter()与getOutputStream()都使用了GZipOutputStream类。这是自定义的一个ServletOutputStream类,它先将数据缓存起来,然后使用JDK自带的GZIP压缩类将数据压缩,并输出到客户端浏览器。GZIP数据压缩与输出都在该类里实现的。
GZipOutputStream.java
package com.rom.util; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.util.zip.GZIPOutputStream; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletResponse; public class GZipOutputStream extends ServletOutputStream { private HttpServletResponse response; private GZIPOutputStream gzipOutputStream; private ByteArrayOutputStream byteArrayOutputStream; public GZipOutputStream(HttpServletResponse response) throws IOException { this.response = response; byteArrayOutputStream = new ByteArrayOutputStream(); gzipOutputStream = new GZIPOutputStream(byteArrayOutputStream); } public void write(int b) throws IOException { gzipOutputStream.write(b); } public void close() throws IOException { gzipOutputStream.finish(); byte[] content = byteArrayOutputStream.toByteArray(); response.addHeader("Content-Encoding", "gzip"); response.addHeader("Content-Length", Integer.toString(content.length)); ServletOutputStream out = response.getOutputStream(); out.write(content); out.close(); } public void flush() throws IOException { gzipOutputStream.flush(); } public void write(byte[] b, int off, int len) throws IOException { gzipOutputStream.write(b, off, len); } public void write(byte[] b) throws IOException { gzipOutputStream.write(b); } }
添加xml配置文件
<filter> <display-name>GzipFilter</display-name> <filter-name>GzipFilter</filter-name> <filter-class>com.rom.util.GzipFilter</filter-class> </filter> <filter-mapping> <filter-name>GzipFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
相关文章推荐
- XenServer架构之HA概述
- XenServer的架构之Xenopsd组件架构与运行机制
- XenServer架构之XAPI的调用流程
- XenServer架构之XAPI
- XenServer的架构2
- 架构设计:系统间通信(34)——被神化的ESB(上)
- 微服务实战(一):微服务架构的优势与不足
- 简洁的HTML5和CSS3免费企业网站模板源码下载
- 网站设计原则
- 网站性能优化时Cookie常用的优化方式
- 关于网站SEO
- HiveServer2的高可用-HA配置
- 一个架构师谈什么是架构以及怎么成为一个架构师
- 一份让老板满意并且有价值的运营方案什么样子?(上)
- 从香港虚拟主机开始 唤醒沉睡中的网站
- 推荐几个不错的网站
- 从香港虚拟主机开始 唤醒沉睡中的网站
- 老司机教你做一个“你懂的”的网站
- 从香港虚拟主机开始 唤醒沉睡中的网站
- 高可用系统开发可能遇到的问题