tomcat配置gzip压缩与解压缩

忘是亡心i 2022-08-21 01:28 552阅读 0赞

前言

最近的做的项目中,遇到这么一个问题:服务器返回给客户端的xml报文数据量太大,费时耗流量,于是要求服务端添加gzip支持,现在把整个流程写下来,以供以后有需要时参考。gzip是一种文件压缩算法,http服务器端添加支持后,客户端请求时添加请求头信息Accept-Encoding:gzip即可享受服务端的gzip压缩服务,获取压缩后的数据,极大减小网络传输数据,提高响应速度和减少流量。当然,如果客户端http请求中没有添加Accept-Encoding:gzip请求头信息,服务器端返回的依旧是未压缩的数据。

服务端gzip支持

首先,写一个简单的servlet程序,读取一个文本文件,然后返回给客户端

  1. protected void service(HttpServletRequest request, HttpServletResponse response)
  2. throws ServletException {
  3. String xmlFileName = "books.xml";
  4. try {
  5. response.setContentType("text/html;charset=utf-8");
  6. String filePath=this.getServletConfig().getServletContext().getRealPath("/"+xmlFileName);
  7. File file = new File(filePath);
  8. //文件原本大小
  9. System.out.println("服务端文件大小:"+file.length()+"byte");
  10. FileInputStream fileIn =new FileInputStream(file);
  11. ByteArrayOutputStream baos = new ByteArrayOutputStream();
  12. byte[] b = new byte[1024];
  13. int i = 0;
  14. while ((i = fileIn.read(b)) != -1) {
  15. baos.write(b, 0, i);
  16. }
  17. ServletOutputStream out = response.getOutputStream();
  18. out.write(baos.toByteArray());
  19. out.flush();
  20. out.close();
  21. fileIn.close();
  22. } catch (FileNotFoundException e) {
  23. e.printStackTrace();
  24. } catch (IOException e) {
  25. e.printStackTrace();
  26. }
  27. }

然后,tomcat配置gzip支持,具体做法是在server.xml配置文件中添加以下属性

  1. <Connector connectionTimeout="20000" port="8080" protocol="HTTP/1.1" redirectPort="8443"
  2. compression="on"
  3. compressionMinSize="2048"
  4. noCompressionUserAgents="gozilla"
  5. compressableMimeType="text/html,text/xml,text/plain,text/css,text/javascript,application/javascript"/>

主要参数解释

compression:开启压缩,可选值:”on”开启,”off”关闭,”force”任何情况都开启

compressionMinSize:指定压缩的最小数据大小,单位B,默认2048B

noCompressionUserAgents:正则表达式,匹配的UA将不会被压缩,默认空

compressableMimeType:会被压缩的MIME类型列表,多个逗号隔开,默认值:text/html,text/xml,text/plain,text/css,text/javascript,application/javascript
具体参考官网: http://tomcat.apache.org/tomcat-7.0-doc/config/http.html

客户端请求及解压缩

首先,通过HttpURLConnection发起请求,看一看未添加Accept-Encoding:gzip请求头的情况,代码如下

  1. public static void main(String[] args) throws Exception{
  2. StringBuffer url = new StringBuffer("http://127.0.0.1:8080/GZip/GetBook");
  3. URL u = new URL(url.toString());
  4. HttpURLConnection conn;
  5. InputStream in;
  6. conn = (HttpURLConnection) u.openConnection();
  7. conn.setRequestMethod("POST");
  8. conn.setDoInput(true);
  9. conn.setDoOutput(true);
  10. in = conn.getInputStream();
  11. System.out.println("客户端获取数据大小:"+in.available()+"byte");
  12. BufferedReader reader = new BufferedReader(new InputStreamReader(in));
  13. String line = null;
  14. StringBuffer sb = new StringBuffer();
  15. while((line = reader.readLine())!= null){
  16. sb.append(line);
  17. }
  18. //打印获取到的数据
  19. System.out.println(sb.toString());
  20. in.close();
  21. conn.disconnect();
  22. }

控制台信息:

Center

Center 1

数据未压缩,数据大小一致

接着,再来看看添加Accept-Encoding:gzip请求头的情况,在上面的客户端代码添加下面一句

  1. conn.addRequestProperty("Accept-Encoding", "gzip");

请求下:

Center 2
数据已经被压缩,有原来的8365bB变成258B,gzip格式的数据显示为乱码,所有现在需要做的是对数据进行解压缩,使用JDK自带的GZIPInputStream就能搞定

  1. GZIPInputStream gzipIn = new GZIPInputStream(in);
  2. BufferedReader reader = new BufferedReader(new InputStreamReader(gzipIn));

结果如下

Center 3

到此,整个流程基本结束

再插一脚

删除books.xml中的部分数据,使其大小小于配置的最小压缩数据2048B,再次请求,会发现数据不会被压缩

Center 4

Center 5

因为数据格式不是gzip压缩格式,所有使用GZIPInputStream解压缩抛异常了

还有一点,浏览器默认请求头包含Accept-Encoding:gzip,而且会自动解压缩,浏览器不会显示乱码,另外,对于请求头中的deflate和gzip类似,也是一种压缩算法,不过多介绍。

Center 6

插曲

之前通过另一种方式写的服务端发生了件有意思的事,代码如下

  1. PrintWriter out = response.getWriter();
  2. BufferedReader br = new BufferedReader(new InputStreamReader(fileIn));
  3. StringBuffer sb = new StringBuffer();
  4. String line = null;
  5. while ((line = br.readLine())!=null){
  6. sb.append(line);
  7. }
  8. out.write(sb.toString());

然后发现客户端的数据大小总比服务端的少了点,找了好久才查出原因。原来是BufferedReader的readLine方法会把每行的回车换行去掉,UTF-8编码下CRLF各占一个字符,所有,数据大小自然变小了。真是浅草才能没马蹄啊,囧。

总结

本文主要写了一个tomcat配置gzip压缩和客户端解压缩的实例,对于不同数据大小下压缩率不尽相同,篇幅有限,不再描述,有兴趣的同学可以自行测试。

发表评论

表情:
评论列表 (有 0 条评论,552人围观)

还没有评论,来说两句吧...

相关阅读

    相关 tomcat配置gzip压缩压缩

    前言 最近的做的项目中,遇到这么一个问题:服务器返回给客户端的xml报文数据量太大,费时耗流量,于是要求服务端添加gzip支持,现在把整个流程写下来,以供以后有需要时参考

    相关 Gzip压缩数据

    在进行微博数据解析的过程中,遇到了gzip格式的压缩数据,要从这些数据中得到微博信息就首先需要对gzip数据进行解压。 这里采用的解压工具是zlib([http://www.