Springboot 之 Filter 实现 Gzip 压缩超大 json 对象

简介在项目中,存在传递超大 json 数据的场景 。直接传输超大 json 数据的话,有以下两个弊端

  • 占用网络带宽,而有些云产品就是按照带宽来计费的 , 间接浪费了钱
  • 传输数据大导致网络传输耗时较长为了避免直接传输超大 json 数据,可以对 json 数据进行 Gzip 压缩后,再进行网络传输 。
  • 请求头添加 Content-Encoding 标识,传输的数据进行过压缩
  • Servlet Filter 拦截请求,对压缩过的数据进行解压
  • HttpServletRequestWrapper 包装 , 把解压的数据写入请求体
pom.xml 引入依赖<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.olive</groupId> <artifactId>request-uncompression</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>request-uncompression</name> <url>http://maven.apache.org</url> <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.5.14</version><relativePath /> <!-- lookup parent from repository --> </parent> <properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target> </properties> <dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>com.alibaba.fastjson2</groupId><artifactId>fastjson2</artifactId><version>2.0.14</version></dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.9.0</version></dependency> </dependencies></project>创建压缩工具类GzipUtils 类提供压缩解压相关方法
package com.olive.utils;import com.alibaba.fastjson2.JSON;import com.olive.vo.ArticleRequestVO;import lombok.extern.slf4j.Slf4j;import org.apache.commons.io.FileUtils;import java.io.*;import java.util.zip.GZIPInputStream;import java.util.zip.GZIPOutputStream;@Slf4jpublic class GzipUtils {private static final String GZIP_ENCODE_UTF_8 = "UTF-8";/*** 字符串压缩为GZIP字节数组** @param str* @return*/public static byte[] compress(String str) {return compress(str, GZIP_ENCODE_UTF_8);}/*** 字符串压缩为GZIP字节数组** @param str* @param encoding* @return*/public static byte[] compress(String str, String encoding) {if (str == null || str.length() == 0) {return null;}ByteArrayOutputStream out = new ByteArrayOutputStream();GZIPOutputStream gzip = null;try {gzip = new GZIPOutputStream(out);gzip.write(str.getBytes(encoding));} catch (IOException e) {log.error("compress>>", e);}finally {if(gzip!=null){try {gzip.close();} catch (IOException e) {}}}return out.toByteArray();}/*** GZIP解压缩** @param bytes* @return*/public static byte[] uncompress(byte[] bytes) {if (bytes == null || bytes.length == 0) {return null;}ByteArrayOutputStream out = new ByteArrayOutputStream();ByteArrayInputStream in = new ByteArrayInputStream(bytes);GZIPInputStream unGzip = null;try {unGzip = new GZIPInputStream(in);byte[] buffer = new byte[256];int n;while ((n = unGzip.read(buffer)) >= 0) {out.write(buffer, 0, n);}} catch (IOException e) {log.error("uncompress>>", e);}finally {if(unGzip!=null){try {unGzip.close();} catch (IOException e) {}}}return out.toByteArray();}/*** 解压并返回String** @param bytes* @return*/public static String uncompressToString(byte[] bytes) throws IOException {return uncompressToString(bytes, GZIP_ENCODE_UTF_8);}/*** @param bytes* @return*/public static byte[] uncompressToByteArray(byte[] bytes) throws IOException {return uncompressToByteArray(bytes, GZIP_ENCODE_UTF_8);}/*** 解压成字符串** @param bytes压缩后的字节数组* @param encoding 编码方式* @return 解压后的字符串*/public static String uncompressToString(byte[] bytes, String encoding) throws IOException {byte[] result = uncompressToByteArray(bytes, encoding);return new String(result);}/*** 解压成字节数组** @param bytes* @param encoding* @return*/public static byte[] uncompressToByteArray(byte[] bytes, String encoding) throws IOException {if (bytes == null || bytes.length == 0) {return null;}ByteArrayOutputStream out = new ByteArrayOutputStream();ByteArrayInputStream in = new ByteArrayInputStream(bytes);GZIPInputStream unGzip = null;try {unGzip = new GZIPInputStream(in);byte[] buffer = new byte[256];int n;while ((n = unGzip.read(buffer)) >= 0) {out.write(buffer, 0, n);}return out.toByteArray();} catch (IOException e) {log.error("uncompressToByteArray>>", e);throw new IOException("解压缩失败!");}finally {if(unGzip!=null){unGzip.close();}}}/*** 将字节流转换成文件** @param filename* @param data* @throws Exception*/public static void saveFile(String filename, byte[] data) throws Exception {FileOutputStream fos = null;try {if (data != null) {String filepath = "/" + filename;File file = new File(filepath);if (file.exists()) {file.delete();}fos = new FileOutputStream(file);fos.write(data, 0, data.length);fos.flush();System.out.println(file);}}catch (Exception e){throw e;}finally {if(fos!=null){fos.close();}}}}

推荐阅读