springboot集成gzip和zip数据压缩传输-满足2k数据自动压缩(适用大数据信息传输)

文章目录

1)、springboot的gzip压缩-满足2k数据自动压缩

1.1后端压缩
java 复制代码
 @GetMapping(value = "/data", produces = "application/json")
    public void getData(HttpServletResponse response) throws IOException {
        String data = "your large data here"; // Replace with actual large data

        response.setHeader("Content-Encoding", "gzip");
        response.setContentType("application/json");

        try (OutputStream os = response.getOutputStream();
             GZIPOutputStream gzipOutputStream = new GZIPOutputStream(os)) {
            gzipOutputStream.write(data.getBytes());
        }
    }
1.2前端解压
js 复制代码
fetch('/api/data', {
    headers: {
        'Accept-Encoding': 'gzip'
    }
})
.then(response => {
    if (response.ok) {
        return response.blob();
    }
    throw new Error('Network response was not ok.');
})
.then(blob => {
    const reader = new FileReader();
    reader.onload = () => {
        const decompressedData = pako.inflate(reader.result, { to: 'string' });
        console.log(JSON.parse(decompressedData));
    };
    reader.readAsArrayBuffer(blob);
})
.catch(error => {
    console.error('There was a problem with your fetch operation:', error);
});
1.3 满足最小响应大小(2KB)和指定MIME类型的响应进行GZIP压缩

将为JSON、XML、文本和JavaScript以及CSS等类型的响应启用GZIP压缩,并且响应大小至少需要2KB才会被压缩

yml配置
yml 复制代码
# application.yml
server:
  compression:
    enabled: true
    mime-types: application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/css
    min-response-size: 2048
自定义配置或者使用Java配置

创建了一个ShallowEtagHeaderFilter bean和一个GzipCompressingFilter bean,后者会对满足最小响应大小(2KB)和指定MIME类型的响应进行GZIP压缩

复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.web.filter.ShallowEtagHeaderFilter;
 
import java.util.Arrays;
import java.util.List;
 
@Configuration
public class GzipConfig {
 
    @Bean
    public ShallowEtagHeaderFilter shallowEtagHeaderFilter() {
        return new ShallowEtagHeaderFilter();
    }
 
    @Bean
    public GzipCompressingFilter gzipCompressingFilter() {
        GzipCompressingFilter filter = new GzipCompressingFilter();
        filter.setMinGzipSize(2048);
        List<String> mimeTypes = Arrays.asList("text/html", "text/xml", "text/plain", "text/css", "application/javascript", "application/json", "application/xml");
        filter.setMimeTypes(mimeTypes);
        return filter;
    }
}

2)、gzip压缩

1.1接口使用-数据压缩发送前端
java 复制代码
    @Autowired
    private GzipUtils gzipUtils;
    
    @RequestMapping(value = "testGzip", method = RequestMethod.POST)
    public JSONBeansResponse testGzip(@RequestBody Map<String, String> map) throws IOException {
        if (null != map) {
            String sqlStr = map.get("paramStr");
            // 调用数据库获取数据
            Map<String, Object> resMap = testMapper.findInfo(sqlStr);
            String dataStr = JSONObject.toJSONString(resMap);
            // 开始压缩数据
            byte[] compress1 = gzipUtils.compress(dataStr);
            String FileBuf = Base64.getEncoder().encodeToString(compress1);
            return new JSONBeansResponse<>(FileBuf);
        }
        return new JSONBeansResponse<>(new ArrayList<>(0));
    }
1.2 接口使用-数据解压来自前端来的压缩数据
java 复制代码
    @RequestMapping(value = "testUnGzip", method = RequestMethod.POST)
    public JSONBeansResponse testUnGzip(@RequestBody Map<String, String> map) throws IOException {
        if (null != map) {
            String dataStream = map.get("dataStream ");
            byte[] decode = Base64.getDecoder().decode(dataStream);
            byte[] compress1 = gzipUtils.uncompress(decode);
            String dataStr = new String(compress1);
            Map<String, Object> res = JSONObject.parseObject(dataStr, Map.class);
            return new JSONBeansResponse<>(res);
        }
        return new JSONBeansResponse<>(new ArrayList<>(0));
    }

遇到问题

解压时候报错:java.util.zip.ZipException: Not in GZIP format

解决方案:在转换为字符串时,一定要使用ISO-8859-1这样的单字节编码

java 复制代码
 public R getLikeKeys(HttpServletRequest request, HttpServletResponse response, String data)
    {
        String data = "xxxxxxxx"; // 前端传来的数据
        String data3=new String(data.getBytes(), StandardCharsets.ISO_8859_1);
	}
1.3 GzipUtils工具类
java 复制代码
package com.自己的包.util;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;
/**
 * @program: tool_java
 * @description:
 * @author: sfp
 * @create: 2021-11-30 14:33
 **/
@Component
public class GzipUtils {
    /**
     * 压缩
     *
     * @param data 数据流
     * @return 压缩数据流
     * @throws IOException 异常
     */
    public byte[] compress(byte[] data) throws IOException {
        if (data == null || data.length == 0) {
            return null;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        GZIPOutputStream gzip = new GZIPOutputStream(out);
        gzip.write(data);
        gzip.close();
        return out.toByteArray();
    }
    /**
     * 压缩
     *
     * @param str 需要压缩数据信息
     * @return 压缩数据流
     * @throws IOException 异常
     */
    public byte[] compress(String str) throws IOException {
        if (str == null || str.length() == 0) {
            return null;
        }
        return compress(str.getBytes(StandardCharsets.UTF_8));
    }
    /**
     * 解压
     *
     * @param data 欲解压数据流
     * @return 原数据流
     * @throws IOException 异常
     */
    public byte[] uncompress(byte[] data) throws IOException {
        if (data == null || data.length == 0) {
            return data;
        }
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        ByteArrayInputStream in = new ByteArrayInputStream(data);
        GZIPInputStream gunzip = new GZIPInputStream(in);
        byte[] buffer = new byte[1024];
        int n;
        while ((n = gunzip.read(buffer)) >= 0) {
            out.write(buffer, 0, n);
        }
        gunzip.close();
        in.close();
        return out.toByteArray();
    }
    /**
     * 解压
     *
     * @param str 欲解压数据字符串
     * @return 原数据
     * @throws IOException 异常
     */
    public String uncompress(String str) throws IOException {
        if (str == null || str.length() == 0) {
            return str;
        }
        byte[] data = uncompress(str.getBytes(StandardCharsets.ISO_8859_1));
        return new String(data);
    }
}

3)、前端压缩数据

引入pako库

首先,通过npm安装pako库:
npm install pako

如果你不使用npm,也可以通过CDN引入pako库:
<script src="https://cdnjs.cloudflare.com/ajax/libs/pako/2.0.4/pako.min.js"></script>

1.2 实现GzipUtils类

然后,在JavaScript中实现GzipUtils类:

js 复制代码
class GzipUtils {
    /**
     * 压缩
     *
     * @param {Uint8Array|ArrayBuffer} data 数据流
     * @return {Uint8Array} 压缩数据流
     */
    static compress(data) {
        if (!data || data.length === 0) {
            return null;
        }
        return pako.gzip(data);
    }

    /**
     * 压缩
     *
     * @param {string} str 需要压缩数据信息
     * @return {Uint8Array} 压缩数据流
     */
    static compressString(str) {
        if (!str || str.length === 0) {
            return null;
        }
        const utf8Data = new TextEncoder().encode(str);
        return this.compress(utf8Data);
    }

    /**
     * 解压
     *
     * @param {Uint8Array|ArrayBuffer} data 欲解压数据流
     * @return {Uint8Array} 原数据流
     */
    static uncompress(data) {
        if (!data || data.length === 0) {
            return data;
        }
        return pako.ungzip(data);
    }

    /**
     * 解压
     *
     * @param {string} str 欲解压数据字符串
     * @return {string} 原数据
     */
    static uncompressString(str) {
        if (!str || str.length === 0) {
            return str;
        }
        const compressedData = new Uint8Array([...str].map(char => char.charCodeAt(0)));
        const uncompressedData = this.uncompress(compressedData);
        return new TextDecoder().decode(uncompressedData);
    }
}
1.3 前端使用示例
js 复制代码
// 使用pako库,确保pako库已引入
// npm install pako
// 或者通过CDN引入 pako.min.js

// 压缩字符串
const originalString = "Hello, this is a string to be compressed.";
const compressedData = GzipUtils.compressString(originalString);
console.log("Compressed Data:", compressedData);

// 解压字符串
const decompressedString = GzipUtils.uncompressString(compressedData);
console.log("Decompressed String:", decompressedString);

// 确保解压后的字符串与原始字符串相同
console.assert(originalString === decompressedString, "Strings do not match!");

4)、zip压缩方案

接口使用-数据压缩发送前端
java 复制代码
    @Autowired
    private ZipUtils zipUtils;
    @RequestMapping(value = "testzip", method = RequestMethod.POST)
    public JSONBeansResponse testzip(@RequestBody Map<String, String> map) throws IOException {
        String sqlStr = map.get("paramStr");
        List<Map<String, Object>> resMap = testMapper.findInfo(sqlStr);;
        String dataStr = JSONObject.toJSONString(resMap);
        // 开始压缩数据
        byte[] compress1 = zipUtils.compress(dataStr);
        String FileBuf = Base64.getEncoder().encodeToString(compress1);
        // 开始解压数据
        String s = zipUtils.uncompress(FileBuf);
        List<Map> arrayLists = JSONObject.parseArray(s, Map.class);
        return new JSONBeansResponse<>(arrayLists);
    }
接口使用-数据解压来自前端来的压缩数据
ZipUtils工具类
java 复制代码
package com.自己的包.util;
import org.springframework.stereotype.Component;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;
/**
* @program: tool_java
* @description: zip压缩工具
* @author: sfp
* @create: 2021-12-01 14:11
**/
@Component
public class ZipUtils {
/** 压缩
    * @param data  原数据流
    * @return 压缩后的数据流
    * @throws IOException 异常
    */
   public byte[] compress(byte[] data) throws IOException {
       if (data == null || data.length == 0) {
           return null;
       }
       ByteArrayOutputStream out = new ByteArrayOutputStream();
       ZipOutputStream gzip = new ZipOutputStream(out);
       gzip.putNextEntry(new ZipEntry("json"));
       gzip.write(data);
       gzip.close();
       return out.toByteArray();
   }
   /** 压缩
    * @param str  原数据字符串
    * @return 压缩后的数据流
    * @throws IOException 异常
    */
   public byte[] compress(String str) throws IOException {
       if (str == null || str.length() == 0) {
           return null;
       }
       return compress(str.getBytes(StandardCharsets.UTF_8));
   }
   /** 解压缩
    * @param data  压缩后的数据流
    * @return 原数据的数据流
    * @throws IOException 异常
    */
   public byte[] uncompress(byte[] data) throws IOException {
       if (data == null || data.length == 0) {
           return data;
       }
       ByteArrayOutputStream out = new ByteArrayOutputStream();
       ByteArrayInputStream in = new ByteArrayInputStream(data);
       ZipInputStream gunzip = new ZipInputStream(in);
       ZipEntry nextEntry = gunzip.getNextEntry();
       while (nextEntry != null) {
           final String fileName = nextEntry.getName();
           if (nextEntry.isDirectory()) {
               nextEntry = gunzip.getNextEntry();
           } else if (fileName.equals("json")) {
               byte[] buffer = new byte[1024];
               int n;
               while ((n = gunzip.read(buffer)) >= 0) {
                   out.write(buffer, 0, n);
               }
               gunzip.close();
               in.close();
               return out.toByteArray();
           }
       }
       return out.toByteArray();
   }
   /** 解压
    * @param str  压缩后的base64流
    * @return 原数据字符串
    * @throws IOException 异常
    */
   public String uncompress(String str) throws IOException {
       if (str == null || str.length() == 0) {
           return str;
       }
       byte[] data = uncompress(Base64.getDecoder().decode(str));
       return new String(data);
   }
}
相关推荐
消失在人海中10 分钟前
hive 数据简介
大数据
xjz184215 分钟前
Liquibase管理数据库变更脚本的最佳实践
后端
眼镜chen16 分钟前
springboot项目引用外部jar包,linux部署后启动失败,找不到jar包
linux·spring boot·jar
逍遥运德33 分钟前
java牛排烧烤技术
java·spring boot·架构
K线引力场33 分钟前
基于 EMA12 指标结合 iTick 外汇报价 API 、股票报价API、指数报价API的量化策略编写与回测
大数据·openai
遥不可及38733 分钟前
Spring Boot 配置文件切换的全面指南
后端
idMiFeng36 分钟前
Go语言反射机制在数据库同步中的实战应用 —— 动态赋值与类型转换详解
数据库·后端·程序员
Victor35639 分钟前
Dubbo(9)什么是RPC?Dubbo如何实现RPC?
后端
遥不可及38739 分钟前
深入理解 Spring Boot 应用的生命周期:从启动到关闭的全流程解析
后端
一名用户40 分钟前
如何在一个数列里边用新手都会玩得666的交换操作生成全部唯一的序列?(黑马式讲解)
c++·后端