http压缩 Content-Encoding: gzip

  

内容摘录自觉着写的挺好 - http://liuviphui.blog.163.com/blog/static/20227308420141843933379/
下面有具体介绍,还有实例
Gzip是如何压缩的
简单来说, Gzip压缩是在一个文本文件中找出类似的字符串, 并临时替换他们,使整个文件变小。这种形式的压缩对Web来说非常适合, 因为HTML和CSS文件通常包含大量的重复的字符串,例如空格,标签。

压缩的好处
http压缩对纯文本可以压缩至原内容的40%, 从而节省了60%的数据传输。

Gzip的缺点
JPEG这类文件用gzip压缩的不够好。

内容编码类型
HTTP定义了一些标准的内容编码类型,并允许用扩展的形式添加更多的编码。

Content-Encoding header 就用这些标准化的代号来说明编码时使用的算法

Content-Encoding值

gzip  表明实体采用GNU zip编码

compress 表明实体采用Unix的文件压缩程序

deflate  表明实体是用zlib的格式压缩的

identity  表明没有对实体进行编码。当没有Content-Encoding header时, 就默认为这种情况

gzip, compress, 以及deflate编码都是无损压缩算法,用于减少传输报文的大小,不会导致信息损失。 其中gzip通常效率最高, 使用最为广泛。

HTTP压缩的过程
浏览器发送Http request 给Web服务器, request 中有Accept-Encoding: gzip, deflate。 (告诉服务器, 浏览器支持gzip压缩)

Web服务器接到request后, 生成原始的Response, 其中有原始的Content-Type和Content-Length。

Web服务器通过Gzip,来对Response进行编码, 编码后header中有Content-Type和Content-Length(压缩后的大小), 并且增加了Content-Encoding:gzip.
然后把Response发送给浏览器。

浏览器接到Response后,根据Content-Encoding:gzip来对Response 进行解码。 获取到原始response后, 然后显示出网页

HTTP内容编码和HTTP压缩的区别
HTTP压缩,在HTTP协议中,其实是内容编码的一种。

在http协议中,可以对内容(也就是body部分)进行编码, 可以采用gzip这样的编码。 从而达到压缩的目的。 也可以使用其他的编码把内容搅乱或加密,以此来防止未授权的第三方看到文档的内容。

所以我们说HTTP压缩,其实就是HTTP内容编码的一种。 所以大家不要把HTTP压缩和HTTP内容编码两个概念混淆了。

代码示例:
可以创建一个servelt
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)throws ServletException, IOException {
System.out.println("================ servlet init 2 ===============================");

final String UTF8_CHARSET_ENCODE = "UTF-8";
boolean flag = false;

String str = "34543253245432gfdsgfdsg7654876548fdsasdddddddddddddddddddddddddddddddddddddddddddddddddddddddddd";

byte[] bytes = null;
String clientEncode = req.getHeader("Accept-Encoding");
if(clientEncode.indexOf("gzip")>-1 && str!=null && str.length()>1000){
bytes = Gzip_Test.compress(str.getBytes(UTF8_CHARSET_ENCODE));
flag = true;
resp.setHeader("Content-Encoding", "gzip");
resp.setContentLength(bytes.length);
}
resp.setCharacterEncoding(UTF8_CHARSET_ENCODE);
resp.setContentType("text/html;charset=utf-8");

ServletOutputStream sos = resp.getOutputStream();
if(flag){
sos.write(bytes);
}else{
sos.write(str.getBytes(UTF8_CHARSET_ENCODE));
}
sos.flush();
sos.close();
}

工具处理类:
/**
* @Description:
* @param bytes
* @return byte[]
*/
public static byte[] compress(byte[] bytes) {
try {
ByteArrayInputStream bai = new ByteArrayInputStream(bytes);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
compress(bai, bos);//压缩
bos.flush();
bos.close();
bai.close();
return bos.toByteArray();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}

/**
* @Description: 把输入流中的数据读取到通过压缩流写入到输出六中
* @param bai
* @param bos
*/
private static void compress(InputStream bai,OutputStream bos){
try {
GZIPOutputStream gos = new GZIPOutputStream(bos);
byte[] bs = new byte[1024];
int read = 0;
while((read=bai.read(bs, 0, bs.length))!=-1){
gos.write(bs, 0, read);
}
gos.finish();
gos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}

猜你喜欢

转载自wo-niu.iteye.com/blog/2146147