【spring】通过GZIP压缩提高网络传输效率(可以实现任何资源的gzip压缩、包括AJAX)

gzip是http协议中使用的一种加密算法,客户端向web服务器端发出了请求后,通常情况下服务器端会将页面文件和其他资源,返回到客户端,客户端加载后渲染呈现,这种情况文件一般都比较大,如果开启Gzip ,那么服务器端响应后,会将页面,js,CSS等文本文件或者其他文件通过高压缩算法将其压缩,然后传输到客户端,由客户端的浏览器负责解压缩与呈现。通常能节省40%以上的流量(一般都有60%左右),一些PHP,JSP文件也能够进行压缩。

1、通过WEB服务器打开GZIP压缩服务

目前大多数主流WEB中间件都支持GZIP压缩、下面以Tomcat 为例进行说明:

找到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"

将它改成如下的形式(其实在上面代码的下面已经有了,将他们打开而已。):

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

一般文本类型的静态文件可以通过这种方式压缩后传输、提高传输效率。

已压缩过的静态文件(如图片)进行gzip压缩后大小基本无变化、所以一般不进行压缩。

2、通过过滤器实现gzip压缩

[java] view plaincopy
  1. package com.tyyd.framework.web;
  2. import java.io.IOException;
  3. import javax.servlet.Filter;
  4. import javax.servlet.FilterChain;
  5. import javax.servlet.FilterConfig;
  6. import javax.servlet.ServletException;
  7. import javax.servlet.ServletOutputStream;
  8. import javax.servlet.ServletRequest;
  9. import javax.servlet.ServletResponse;
  10. import javax.servlet.http.HttpServletRequest;
  11. import javax.servlet.http.HttpServletResponse;
  12. import org.apache.commons.io.FilenameUtils;
  13. import org.apache.commons.lang.StringUtils;
  14. import com.tyyd.framework.core.AcwsInfo;
  15. import com.tyyd.framework.core.AcwsMonitorLog;
  16. import com.tyyd.framework.core.BufferedResponse;
  17. import com.tyyd.framework.core.util.ZipUtil;
  18. /**
  19. * HTTP访问过滤器
  20. */
  21. public class PageVisitFilter2 implements Filter {
  22. @Override
  23. public void init(FilterConfig filterConfig) throws ServletException {
  24. }
  25. @Override
  26. public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
  27. //性能监控
  28. long startTime = System.currentTimeMillis();
  29. HttpServletRequest request = (HttpServletRequest)req;
  30. HttpServletResponse response = (HttpServletResponse)res;
  31. String uri = request.getRequestURI();
  32. String ext = FilenameUtils.getExtension(uri);
  33. try{
  34. response.setHeader("Pragma", "No-cache");
  35. response.setHeader("Cache-Control", "no-cache");
  36. response.setDateHeader("Expires", -1);
  37. request.setCharacterEncoding("UTF-8");
  38. response.setCharacterEncoding("UTF-8");
  39. response.setHeader("renderer", "webkit");
  40. response.setHeader("viewport", "width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0 user-scalable=no");
  41. if(isGZipEncoding(request)){
  42. //需要过滤的扩展名:.htm,.html,.jsp,.js,.ajax,.css
  43. String gzippPattern=",.htm,.html,.jsp,.js,.ajax,.css,";
  44. if(StringUtils.indexOf(gzippPattern, ",."+ext+",")!=-1){
  45. BufferedResponse gzipResponse = new BufferedResponse(response);
  46. chain.doFilter(request, gzipResponse);
  47. byte[] srcData = gzipResponse.getResponseData();
  48. byte[] outData = null;
  49. if(srcData.length > 512){
  50. byte[] gzipData = ZipUtil.toGzipBytes(srcData);
  51. response.addHeader("Content-Encoding", "gzip");
  52. response.setContentLength(gzipData.length);
  53. outData = gzipData;
  54. } else {
  55. outData = srcData;
  56. }
  57. ServletOutputStream output = response.getOutputStream();
  58. output.write(outData);
  59. output.flush();
  60. } else {
  61. chain.doFilter(request, response);
  62. }
  63. return;
  64. }
  65. chain.doFilter(request, response);
  66. }catch(Exception e){
  67. }finally{
  68. AcwsMonitorLog.warnHttpVisit(startTime, request);
  69. }
  70. }
  71. @Override
  72. public void destroy() {
  73. }
  74. /**
  75. * 判断浏览器是否支持GZIP
  76. * @param request
  77. * @return
  78. */
  79. private boolean isGZipEncoding(HttpServletRequest request){
  80. boolean flag=false;
  81. String encoding=request.getHeader("Accept-Encoding");
  82. if(encoding.indexOf("gzip")!=-1){
  83. flag=true;
  84. }
  85. return flag;
  86. }
  87. }
[java] view plaincopy
  1. package com.tyyd.framework.core;
  2. import java.io.IOException;
  3. import java.io.OutputStreamWriter;
  4. import java.io.PrintWriter;
  5. import javax.servlet.ServletOutputStream;
  6. import javax.servlet.http.HttpServletResponse;
  7. import javax.servlet.http.HttpServletResponseWrapper;
  8. public class BufferedResponse extends HttpServletResponseWrapper {
  9. public static final int OT_NONE = 0, OT_WRITER = 1, OT_STREAM = 2;
  10. private BufferedOutputStream outputStream = null;
  11. private PrintWriter writer = null;
  12. private int outputType = OT_NONE;
  13. public BufferedResponse(HttpServletResponse response) {
  14. super(response);
  15. outputStream = new BufferedOutputStream();
  16. }
  17. public PrintWriter getWriter() throws IOException {
  18. if (outputType == OT_STREAM)
  19. throw new IllegalStateException();
  20. else if (outputType == OT_WRITER)
  21. return writer;
  22. else {
  23. outputType = OT_WRITER;
  24. writer = new PrintWriter(new OutputStreamWriter(outputStream,
  25. getCharacterEncoding()), true);
  26. return writer;
  27. }
  28. }
  29. public ServletOutputStream getOutputStream() throws IOException {
  30. if (outputType == OT_WRITER)
  31. throw new IllegalStateException();
  32. else if (outputType == OT_STREAM)
  33. return outputStream;
  34. else {
  35. outputType = OT_STREAM;
  36. return outputStream;
  37. }
  38. }
  39. public void flushBuffer() throws IOException {
  40. try{writer.flush();}catch(Exception e){}
  41. try{outputStream.flush();}catch(Exception e){}
  42. }
  43. public void reset() {
  44. outputType = OT_NONE;
  45. outputStream.reset();
  46. }
  47. public byte[] getResponseData() throws IOException {
  48. flushBuffer();
  49. return outputStream.toByteArray();
  50. }
  51. }
[java] view plaincopy
  1. /**
  2. * 版权所有:
  3. * 项目名称:框架
  4. * 创建者: Wangdf
  5. * 创建日期: 2015-2-27
  6. * 文件说明: AJAX 缓存输出流
  7. */
  8. package com.tyyd.framework.core;
  9. import java.io.ByteArrayOutputStream;
  10. import java.io.IOException;
  11. import javax.servlet.ServletOutputStream;
  12. public class BufferedOutputStream extends ServletOutputStream {
  13. private ByteArrayOutputStream outputStream = null;
  14. public BufferedOutputStream(){
  15. outputStream = new ByteArrayOutputStream(1024);
  16. }
  17. /**
  18. * Writes the specified byte to this output stream. The general
  19. * contract for <code>write</code> is that one byte is written
  20. * to the output stream. The byte to be written is the eight
  21. * low-order bits of the argument <code>b</code>. The 24
  22. * high-order bits of <code>b</code> are ignored.
  23. * <p>
  24. * Subclasses of <code>OutputStream</code> must provide an
  25. * implementation for this method.
  26. *
  27. * @param      b   the <code>byte</code>.
  28. * @exception  IOException  if an I/O error occurs. In particular,
  29. *             an <code>IOException</code> may be thrown if the
  30. *             output stream has been closed.
  31. */
  32. public void write(int b) throws IOException {
  33. outputStream.write(b);
  34. }
  35. /**
  36. * Writes <code>b.length</code> bytes from the specified byte array
  37. * to this output stream. The general contract for <code>write(b)</code>
  38. * is that it should have exactly the same effect as the call
  39. * <code>write(b, 0, b.length)</code>.
  40. *
  41. * @param      b   the data.
  42. * @exception  IOException  if an I/O error occurs.
  43. * @see        java.io.OutputStream#write(byte[], int, int)
  44. */
  45. public void write(byte b[]) throws IOException {
  46. outputStream.write(b);
  47. }
  48. /**
  49. * Writes <code>len</code> bytes from the specified byte array
  50. * starting at offset <code>off</code> to this output stream.
  51. * The general contract for <code>write(b, off, len)</code> is that
  52. * some of the bytes in the array <code>b</code> are written to the
  53. * output stream in order; element <code>b[off]</code> is the first
  54. * byte written and <code>b[off+len-1]</code> is the last byte written
  55. * by this operation.
  56. * <p>
  57. * The <code>write</code> method of <code>OutputStream</code> calls
  58. * the write method of one argument on each of the bytes to be
  59. * written out. Subclasses are encouraged to override this method and
  60. * provide a more efficient implementation.
  61. * <p>
  62. * If <code>b</code> is <code>null</code>, a
  63. * <code>NullPointerException</code> is thrown.
  64. * <p>
  65. * If <code>off</code> is negative, or <code>len</code> is negative, or
  66. * <code>off+len</code> is greater than the length of the array
  67. * <code>b</code>, then an <tt>IndexOutOfBoundsException</tt> is thrown.
  68. *
  69. * @param      b     the data.
  70. * @param      off   the start offset in the data.
  71. * @param      len   the number of bytes to write.
  72. * @exception  IOException  if an I/O error occurs. In particular,
  73. *             an <code>IOException</code> is thrown if the output
  74. *             stream is closed.
  75. */
  76. public void write(byte b[], int off, int len) throws IOException {
  77. outputStream.write(b, off, len);
  78. }
  79. /**
  80. * Writes a <code>String</code> to the client,
  81. * without a carriage return-line feed (CRLF)
  82. * character at the end.
  83. *
  84. *
  85. * @param s         the <code>String</code> to send to the client
  86. *
  87. * @exception IOException   if an input or output exception occurred
  88. *
  89. */
  90. public void print(String s) throws IOException {
  91. print(s, "UTF-8");
  92. }
  93. public void print(String s, String charsetName) throws IOException {
  94. /*
  95. * 解决中文乱码问题
  96. */
  97. outputStream.write(s.getBytes(charsetName));
  98. }
  99. /**
  100. * Writes a <code>boolean</code> value to the client,
  101. * with no carriage return-line feed (CRLF)
  102. * character at the end.
  103. *
  104. * @param b         the <code>boolean</code> value
  105. *              to send to the client
  106. *
  107. * @exception IOException   if an input or output exception occurred
  108. *
  109. */
  110. public void print(boolean b) throws IOException {
  111. print(b?"true":"false");
  112. }
  113. /**
  114. * Writes a character to the client,
  115. * with no carriage return-line feed (CRLF)
  116. * at the end.
  117. *
  118. * @param c         the character to send to the client
  119. *
  120. * @exception IOException   if an input or output exception occurred
  121. *
  122. */
  123. public void print(char c) throws IOException {
  124. print(String.valueOf(c));
  125. }
  126. /**
  127. *
  128. * Writes an int to the client,
  129. * with no carriage return-line feed (CRLF)
  130. * at the end.
  131. *
  132. * @param i         the int to send to the client
  133. *
  134. * @exception IOException   if an input or output exception occurred
  135. *
  136. */
  137. public void print(int i) throws IOException {
  138. print(String.valueOf(i));
  139. }
  140. /**
  141. *
  142. * Writes a <code>long</code> value to the client,
  143. * with no carriage return-line feed (CRLF) at the end.
  144. *
  145. * @param l         the <code>long</code> value
  146. *              to send to the client
  147. *
  148. * @exception IOException   if an input or output exception
  149. *              occurred
  150. *
  151. */
  152. public void print(long l) throws IOException {
  153. print(String.valueOf(l));
  154. }
  155. /**
  156. *
  157. * Writes a <code>float</code> value to the client,
  158. * with no carriage return-line feed (CRLF) at the end.
  159. *
  160. * @param f         the <code>float</code> value
  161. *              to send to the client
  162. *
  163. * @exception IOException   if an input or output exception occurred
  164. *
  165. *
  166. */
  167. public void print(float f) throws IOException {
  168. print(String.valueOf(f));
  169. }
  170. /**
  171. *
  172. * Writes a <code>double</code> value to the client,
  173. * with no carriage return-line feed (CRLF) at the end.
  174. *
  175. * @param d         the <code>double</code> value
  176. *              to send to the client
  177. *
  178. * @exception IOException   if an input or output exception occurred
  179. *
  180. */
  181. public void print(double d) throws IOException {
  182. print(String.valueOf(d));
  183. }
  184. /**
  185. * Writes a carriage return-line feed (CRLF)
  186. * to the client.
  187. *
  188. *
  189. *
  190. * @exception IOException   if an input or output exception occurred
  191. *
  192. */
  193. public void println() throws IOException {
  194. print("\r\n");
  195. }
  196. /**
  197. * Writes a <code>String</code> to the client,
  198. * followed by a carriage return-line feed (CRLF).
  199. *
  200. *
  201. * @param s         the <code>String</code> to write to the client
  202. *
  203. * @exception IOException   if an input or output exception occurred
  204. *
  205. */
  206. public void println(String s){
  207. println(s, "UTF-8");
  208. }
  209. public void println(String s, String charsetName){
  210. /*
  211. * 解决中文乱码问题
  212. */
  213. try {
  214. print(s,charsetName);
  215. println();
  216. } catch (IOException e) {
  217. throw new RuntimeException(e);
  218. }
  219. }
  220. /**
  221. *
  222. * Writes a <code>boolean</code> value to the client,
  223. * followed by a
  224. * carriage return-line feed (CRLF).
  225. *
  226. *
  227. * @param b         the <code>boolean</code> value
  228. *              to write to the client
  229. *
  230. * @exception IOException   if an input or output exception occurred
  231. *
  232. */
  233. public void println(boolean b) throws IOException {
  234. print(b);
  235. println();
  236. }
  237. /**
  238. *
  239. * Writes a character to the client, followed by a carriage
  240. * return-line feed (CRLF).
  241. *
  242. * @param c         the character to write to the client
  243. *
  244. * @exception IOException   if an input or output exception occurred
  245. *
  246. */
  247. public void println(char c) throws IOException {
  248. print(c);
  249. println();
  250. }
  251. /**
  252. *
  253. * Writes an int to the client, followed by a
  254. * carriage return-line feed (CRLF) character.
  255. *
  256. *
  257. * @param i         the int to write to the client
  258. *
  259. * @exception IOException   if an input or output exception occurred
  260. *
  261. */
  262. public void println(int i) throws IOException {
  263. print(i);
  264. println();
  265. }
  266. /**
  267. *
  268. * Writes a <code>long</code> value to the client, followed by a
  269. * carriage return-line feed (CRLF).
  270. *
  271. *
  272. * @param l         the <code>long</code> value to write to the client
  273. *
  274. * @exception IOException   if an input or output exception occurred
  275. *
  276. */
  277. public void println(long l) throws IOException {
  278. print(l);
  279. println();
  280. }
  281. /**
  282. *
  283. * Writes a <code>float</code> value to the client,
  284. * followed by a carriage return-line feed (CRLF).
  285. *
  286. * @param f         the <code>float</code> value
  287. *              to write to the client
  288. *
  289. *
  290. * @exception IOException   if an input or output exception
  291. *              occurred
  292. *
  293. */
  294. public void println(float f) throws IOException {
  295. print(f);
  296. println();
  297. }
  298. /**
  299. *
  300. * Writes a <code>double</code> value to the client,
  301. * followed by a carriage return-line feed (CRLF).
  302. *
  303. *
  304. * @param d         the <code>double</code> value
  305. *              to write to the client
  306. *
  307. * @exception IOException   if an input or output exception occurred
  308. *
  309. */
  310. public void println(double d) throws IOException {
  311. print(d);
  312. println();
  313. }
  314. /**
  315. * Flushes this output stream and forces any buffered output bytes
  316. * to be written out. The general contract of <code>flush</code> is
  317. * that calling it is an indication that, if any bytes previously
  318. * written have been buffered by the implementation of the output
  319. * stream, such bytes should immediately be written to their
  320. * intended destination.
  321. * <p>
  322. * If the intended destination of this stream is an abstraction provided by
  323. * the underlying operating system, for example a file, then flushing the
  324. * stream guarantees only that bytes previously written to the stream are
  325. * passed to the operating system for writing; it does not guarantee that
  326. * they are actually written to a physical device such as a disk drive.
  327. * <p>
  328. * The <code>flush</code> method of <code>OutputStream</code> does nothing.
  329. *
  330. * @exception  IOException  if an I/O error occurs.
  331. */
  332. public void flush() throws IOException {
  333. outputStream.flush();
  334. }
  335. /**
  336. * Closes this output stream and releases any system resources
  337. * associated with this stream. The general contract of <code>close</code>
  338. * is that it closes the output stream. A closed stream cannot perform
  339. * output operations and cannot be reopened.
  340. * <p>
  341. * The <code>close</code> method of <code>OutputStream</code> does nothing.
  342. *
  343. * @exception  IOException  if an I/O error occurs.
  344. */
  345. public void close() throws IOException {
  346. outputStream.close();
  347. }
  348. /**
  349. * Resets the <code>count</code> field of this byte array output
  350. * stream to zero, so that all currently accumulated output in the
  351. * output stream is discarded. The output stream can be used again,
  352. * reusing the already allocated buffer space.
  353. *
  354. * @see     java.io.ByteArrayInputStream#count
  355. */
  356. public void reset() {
  357. outputStream.reset();
  358. }
  359. public byte[] toByteArray() {
  360. return outputStream.toByteArray();
  361. }
  362. }

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

[html] view plaincopy
  1. <filter>
  2. <filter-name>Page Visit Filter</filter-name>
  3. <filter-class>com.tyyd.framework.web.PageVisitFilter</filter-class>
  4. </filter>
  5. <filter-mapping>
  6. <filter-name>Page Visit Filter</filter-name>
  7. <url-pattern>/*</url-pattern>
  8. </filter-mapping>

3、AJAX也可以通过这种方式压缩

只需知道ajax请求的后缀添加到下面的代码中即可:

//需要过滤的扩展名:.htm,.html,.jsp,.js,.ajax,.css

String gzippPattern=",.htm,.html,.jsp,.js,.ajax,.css,";

【spring】通过GZIP压缩提高网络传输效率(可以实现任何资源的gzip压缩、包括AJAX)相关推荐

  1. 从 Gzip 压缩 SVG 说起 — 论如何减小资源文件的大小

    原文地址:Of SVG, Minification and Gzip 原文作者:Anton Khlynovskiy 译文出自:掘金翻译计划 本文永久链接:github.com/xitu/gold-m- ...

  2. 分析蠕虫及压缩的网络流量

    利用压缩来分析蠕虫病毒和网络数据 摘要 网络蠕虫已经对系统和网络运作构成分布广泛的威胁.为了更有效与蠕虫对抗,分析最新的发现的蠕虫程序和攻击方式是有必要的.这篇文章说明了如何利用基于Kolmogoro ...

  3. 通过多线程压缩提高生成 Zip 文件的效率

    在很多情况下,需要用 Zip 格式保存数据文档.当数据量较大时(超过100M),就会明显感觉到保存文件耗时很长(超过10秒),这样的用户体验难以接受,想要优化. 现有开源方案 zlib-ng/zlib ...

  4. CentOS 6.0 图形(图解)安装教程、基本配置、网络配置、软件源配置、安装压缩、语言包 一.准备安装CentOS 6

    CentOS 6.0 图形(图解)安装教程.基本配置.网络配置.软件源配置.安装压缩.语言包 一.准备安装CentOS 6 1.CentOS简介 CentOS 是甚么? CentOS 是一个基于Red ...

  5. 了解什么是服务质量QoS以及如何提高网络性能

    服务质量(QoS)是任何成功网络的关键组成部分.它确保您的数据按时交付到目的地,没有中断或损坏.这有助于提高网络的性能,以及连接到网络的用户的体验.在这篇文章中,我们将探讨什么是服务质量(QoS),如 ...

  6. 公证服务信息_使用多个公证员提高网络吞吐量

    公证服务信息 您是否需要高吞吐量的Corda网络? 网络的吞吐量是否稳定? 您是否已经从其他领域挤出了所有可能的表现? 如果您对这些问题的回答是"是",那么我可能会为您提供一些有用 ...

  7. 多个公证员提高网络吞吐量

    您是否需要非常高吞吐量的Corda网络? 网络的吞吐量是否稳定? 您是否已经从其他领域挤出了所有可能的表现? 如果您对这些问题的回答是"是",那么我可能会为您提供一些有用的信息. ...

  8. linux 使用gzip压缩打包的文件,linux常用的解压,压缩,打包

    gzip zcat [root@linux ~]# gzip [-cdt#] 文件名 [root@linux ~]# zcat 文件名.gz 参数: -c : 将压缩的数据输出到屏幕上,可通过数据流重 ...

  9. 提高网络营销的转化只需掌握这四步

    如何提高网络营销的转化,很多企业在开展网络营销的实战中,很多营销负责人都在想办法提升网站流量,吸引用户眼球,做网站优化营销不单是要吸引用户眼球同时也要让用户对你网站产生一种黏性.今天给大家分享的主题是 ...

最新文章

  1. Vbox共享文件夹不显示了
  2. 学习云计算前景如何?新的一年Linux运维职业选择有哪些?
  3. Notepad++ 搜索功能学习总结
  4. android+无触摸操作,如何在Android中模拟触摸事件?
  5. B09_NumPy迭代数组(控制遍历顺序,修改数组中元素的值,使用外部循环,广播迭代)
  6. 网站架构演变和知识体系
  7. python找房源_Python租房信息分析!找到最适合自己的房源信息!
  8. K8S架构设计及工作流程分析
  9. context.Request.Files post 上传问题件
  10. 用eclipice抓取JS代码
  11. 【UIKit】UITableView 5
  12. 随机分组c语言,用C/C++进行随机分组的实现教程
  13. 根据前序序列创建二叉树
  14. 对链表进行插入排序。从第一个元素开始,该链表可以被认为已经部分排序。每次迭代时,从输入数据中移除一个元素,并原地将其插入到已排好序的链表中。
  15. excel表格如何不需鼠标往下拖动而自动往下填
  16. mathpix安装和使用详细教程
  17. 257套工业机器人SW设计3D图纸 焊接机械手/发那科ABB安川臂模型
  18. 【洛谷】P2298 Mzc和男家丁的游戏*
  19. Gartner 魔力象限:云基础设施和平台服务 2020年
  20. 连涨了三天的股票,该买还是该卖?

热门文章

  1. Appium python adb命令
  2. python turtle_Python简单图形化程序模块——Turtle模块
  3. Android开发:4-2、不同Activity数据的传递
  4. windows 打开和关闭显示器
  5. 341. 扁平化嵌套列表迭代器
  6. ACM第一次集训 - 动态规划问题
  7. Python 获取md5值(hashlib)
  8. 浅谈渗透测试之前期信息搜集
  9. C/C++函数指针与回调函数总结(函数指针数组)
  10. twisted系列教程十三–deferred 中的deferred