之前开发中用到的一个报文压缩的实现方案,简单在这里单独提出来写一下,分为Java和JS两版代码。

Java版代码是服务端使用,用来在各服务端之间发送接收报文使用。JS版是在前端页面上用来查看或者调试接口报文使用的。

Java代码,压缩和解压缩方法


/**
 * 
 * 功能描述:字符串压缩 <br>
 * 将字符串压缩
 *
 * @param str 待压缩的字符串
 * @return 压缩后的字符串
 */
@SuppressWarnings("restriction")
public static String gzip(String str) {
    // 创建字符流
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    GZIPOutputStream gzip = null;
    try {
        // 对字符串进行压缩并写入压缩流
        gzip = new GZIPOutputStream(out);
        gzip.write(str.getBytes());
    } catch (IOException e) {
        String errMsg = e.getMessage();
        logger.error(errMsg);
    } finally {
        if (gzip != null) {
            try {
                gzip.close();
            } catch (IOException e) {
                String errMsg = e.getMessage();
                logger.error(errMsg);
            }
        }
    }
    // 返回压缩后的字符串
    return new sun.misc.BASE64Encoder().encode(out.toByteArray());
}

/**
 * 
 * 功能描述: 字符串解压<br>
 * 将字符串解压
 *
 * @param str 待解压的字符串
 * @return 解压后的字符串
 * @throws Exception
 */
@SuppressWarnings("restriction")
public static String gunzip(String str) {
    // 校验压缩数据
    if (str == null) {
        return null;
    }

    // 创建读取流
    ByteArrayOutputStream out = new ByteArrayOutputStream();
    ByteArrayInputStream in = null;
    // 解压缩流
    GZIPInputStream ginzip = null;
    byte[] compressed = null;
    // 原始字符串
    String decompressed = null;

    try {
        // 进行解压缩操作
        compressed = new sun.misc.BASE64Decoder().decodeBuffer(str);
        in = new ByteArrayInputStream(compressed);
        ginzip = new GZIPInputStream(in);

        byte[] buffer = new byte[BYTE_SIZE];
        int offset = -1;
        while ((offset = ginzip.read(buffer)) != -1) {
            out.write(buffer, 0, offset);
        }
        decompressed = out.toString();
    } catch (IOException e) {
        String errMsg = e.getMessage();
        logger.error(errMsg);
        logger.error("解析压缩字符串异常", e);
    } finally {
        if (ginzip != null) {
            try {
                ginzip.close();
            } catch (IOException e) {
                String errMsg = e.getMessage();
                logger.error(errMsg);
            }
        }
        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                String errMsg = e.getMessage();
                logger.error(errMsg);
            }
        }
        try {
            out.close();
        } catch (IOException e) {
            String errMsg = e.getMessage();
            logger.error(errMsg);
        }
    }
    // 返回原始字符串
    return decompressed;
}

JavaScript代码,js的压缩解压缩需要调用到pako包的内容,可以在https://www.bootcdn.cn/pako/ 上找到需要的版本引用,或者简单点直接把需要min版本代码复制到你需要的页面里, https://cdn.bootcdn.net/ajax/libs/pako/2.0.4/pako.min.js,另外也用到浏览器自带的base64加密解密的方法btoa和atob

// 压缩
zip = (data) => {
    if (!data) return data
    let binaryString = pako.gzip(data,{to: 'string'});
    let arr = Array.from(binaryString);
    let s = "";
    arr.forEach((item, index) => {
        s += String.fromCharCode(item)
    })
    return btoa(s)
}

// 解压
unzip = (b64Data) => {
    let strData = atob(b64Data);
    let charData = strData.split('').map(function (x) {
        return x.charCodeAt(0);
    });
    let binData = new Uint8Array(charData);
    // let data = pako.ungzip(binData);
    let data = pako.ungzip(binData,{to: 'string'});
    return data;
}

大致效果如图