开始之前我们先来简单说说gzip是干什么用的,为什么要用
我们来举个栗子
同一个请求他们使用gzip和不使用是完全两个结果
例子一:正常未通过gzip压缩的返回数据大小是100kb
例子二:添加了gzip压缩的数据的返回数据大小可能只有40-20kb甚至10kb
怎样,各位童鞋应该了解到这个gizp的作用了吧,没错,就是数据压缩。
服务端配置gzip压缩
服务端进行gzip的压缩和解压基本没什么难度,配置tomcat服务器即可
对server.xml
进行修改
<Connector connectionTimeout="20000"
compression="on"
compressionMinSize="50"
noCompressionUserAgents="gozilla, traviata"
compressableMimeType="application/json"
port="8080" protocol="HTTP/1.1" redirectPort="8443"/>
compression
开启压缩
compressionMinSize
最低压缩大小,意思达到多少kb会开启压缩,默认是2048,即2kb
noCompressionUserAgents
以下哪些浏览器不启用压缩
compressableMimeType
压缩的数据类型
至于对html/css/js
等等相关压缩可以在compressableMimeType
中补充,本文因为是对接口方面的压缩所以不再描述
有同学问,我既然压缩了,那就应该有解压啊!
对,没错,童鞋你的问题真多。如果你的客户端是android/ios
的话确实需要自己解压,但是如果你的客户端是浏览器的话,那么,你就不用管了,因为浏览器会帮你做这些工作,前提是你的html版本是html1.1+
(我相信现在也找不到低于这个标准的吧?)
客户端(android/ios)发送和解压gizp数据
客户端方面其实也没什么,就是需要在发送请求的时候告诉服务器,我是支持gzip压缩数据的,请你把数据压一压再给我,怎么给?
通过头文件注册
Accept-Encoding: gzip, deflate
服务器会检测你的请求是否可以使用gzip格式,如果注册了这个头文件,那么服务器自动就会进行gzip的数据压缩返回给客户端
在返回的数据结果集中response的头文件会有这么一个属性
Content-Encoding: gzip
然后客户端只需要捕抓response中的头文件是否包含这个属性,如果包含了则需要对原始数据进行解压,解压出来的就是原始数据了,具体解压代码这里给出java方面的,其他客户端可自行搜索
GZIP解压代码
package com.sspendi.framework.utils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/**
* Gzip 压缩字符串
*/
public class GZIP {
/**
* 字符串的压缩
*
* @param str 待压缩的字符串
* @return 返回压缩后的字符串
* @throws IOException
*/
public static String compress(String str) throws IOException {
if (null == str || str.length() <= 0) {
return str;
}
// 创建一个新的输出流
ByteArrayOutputStream out = new ByteArrayOutputStream();
// 使用默认缓冲区大小创建新的输出流
GZIPOutputStream gzip = new GZIPOutputStream(out);
// 将字节写入此输出流
gzip.write(str.getBytes("utf-8")); //因为后台默认字符集有可能是GBK字符集,所以此处需指定一个字符集
gzip.close();
// 使用指定的 charsetName,通过解码字节将缓冲区内容转换为字符串
return out.toString("ISO-8859-1");
}
/**
* 字符串的解压
*
* @param str 对字符串解压
* @return 返回解压缩后的字符串
* @throws IOException
*/
public static String unCompress(String str) throws IOException {
if (null == str || str.length() <= 0) {
return str;
}
return unCompress(str.getBytes("ISO-8859-1"));
}
public static String unCompress(byte[] bs) throws IOException {
// 创建一个新的输出流
ByteArrayOutputStream out = new ByteArrayOutputStream();
ByteArrayInputStream in = new ByteArrayInputStream(bs);
// 使用默认缓冲区大小创建新的输入流
GZIPInputStream gzip = new GZIPInputStream(in);
byte[] buffer = new byte[256];
int n = 0;
// 将未压缩数据读入字节数组
while ((n = gzip.read(buffer)) >= 0) {
out.write(buffer, 0, n);
}
// 使用指定的 charsetName,通过解码字节将缓冲区内容转换为字符串
return out.toString("utf-8");
}
}
至此,完成客户端与服务端的gzip通信,大大减少了流量。