客户端(android/ios)与java服务端tomcat的gzip实现

开始之前我们先来简单说说gzip是干什么用的,为什么要用

我们来举个栗子
同一个请求他们使用gzip和不使用是完全两个结果
例子一:正常未通过gzip压缩的返回数据大小是100kb
例子二:添加了gzip压缩的数据的返回数据大小可能只有40-20kb甚至10kb
怎样,各位童鞋应该了解到这个gizp的作用了吧,没错,就是数据压缩。

服务端配置gzip压缩

服务端进行gzip的压缩和解压基本没什么难度,配置tomcat服务器即可
server.xml进行修改

"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通信,大大减少了流量。

你可能感兴趣的:(android,j2ee,ios)