当前位置: 首页 > news >正文

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

文章目录

    • 1)、springboot的gzip压缩-满足2k数据自动压缩
        • 1.1后端压缩
        • 1.2前端解压
        • 1.3 满足最小响应大小(2KB)和指定MIME类型的响应进行GZIP压缩
          • yml配置
          • 自定义配置或者使用Java配置
    • 2)、gzip压缩
        • 1.1接口使用-数据压缩发送前端
        • 1.2 接口使用-数据解压来自前端来的压缩数据
        • 1.3 GzipUtils工具类
    • 3)、前端压缩数据
        • 1.2 实现GzipUtils类
        • 1.3 前端使用示例
    • 4)、zip压缩方案
        • 接口使用-数据压缩发送前端
        • 接口使用-数据解压来自前端来的压缩数据
        • ZipUtils工具类

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

1.1后端压缩
 @GetMapping(value = "/data", produces = "application/json")public void getData(HttpServletResponse response) throws IOException {String data = "your large data here"; // Replace with actual large dataresponse.setHeader("Content-Encoding", "gzip");response.setContentType("application/json");try (OutputStream os = response.getOutputStream();GZIPOutputStream gzipOutputStream = new GZIPOutputStream(os)) {gzipOutputStream.write(data.getBytes());}}
1.2前端解压
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配置
# application.yml
server:compression:enabled: truemime-types: application/json,application/xml,text/html,text/xml,text/plain,application/javascript,text/cssmin-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 {@Beanpublic ShallowEtagHeaderFilter shallowEtagHeaderFilter() {return new ShallowEtagHeaderFilter();}@Beanpublic 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接口使用-数据压缩发送前端
    @Autowiredprivate 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 接口使用-数据解压来自前端来的压缩数据
    @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这样的单字节编码

 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工具类
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类:

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 前端使用示例
// 使用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压缩方案

接口使用-数据压缩发送前端
    @Autowiredprivate 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工具类
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);}
}

相关文章:

  • c++将一个复杂的结构体_保存成二进制文件并读取
  • Spark2.0
  • 简单爬虫案例——爬取快手视频
  • BMA530 运动传感器
  • 【LeetCode】976. 三角形的最大周长
  • Kafka 位移
  • rpm包下载
  • 自然语言处理基本知识(1)
  • 【CSS】深入探讨 CSS 的 `calc()` 函数
  • 熊猫烧香是什么?
  • 什么是CC攻击,如何防止网站被CC攻击的方法
  • Spring Cloud LoadBalancer基础入门与应用实践
  • 如何获得更高质量的回答-chatgpt
  • vue为啥监听不了@scroll
  • word2016中新建页面显示出来的页面没有页眉页脚,只显示正文部分。解决办法
  • 9月CHINA-PUB-OPENDAY技术沙龙——IPHONE
  • python3.6+scrapy+mysql 爬虫实战
  • Babel配置的不完全指南
  • CentOS7简单部署NFS
  • chrome扩展demo1-小时钟
  • CNN 在图像分割中的简史:从 R-CNN 到 Mask R-CNN
  • Django 博客开发教程 8 - 博客文章详情页
  • git 常用命令
  • Js基础知识(一) - 变量
  • laravel with 查询列表限制条数
  • Linux快速复制或删除大量小文件
  • MYSQL 的 IF 函数
  • open-falcon 开发笔记(一):从零开始搭建虚拟服务器和监测环境
  • supervisor 永不挂掉的进程 安装以及使用
  • Transformer-XL: Unleashing the Potential of Attention Models
  • 表单中readonly的input等标签,禁止光标进入(focus)的几种方式
  • 订阅Forge Viewer所有的事件
  • 多线程事务回滚
  • 关于字符编码你应该知道的事情
  • 机器人定位导航技术 激光SLAM与视觉SLAM谁更胜一筹?
  • ------- 计算机网络基础
  • 要让cordova项目适配iphoneX + ios11.4,总共要几步?三步
  • 【干货分享】dos命令大全
  • # 透过事物看本质的能力怎么培养?
  • #LLM入门|Prompt#1.7_文本拓展_Expanding
  • #NOIP 2014# day.1 T3 飞扬的小鸟 bird
  • (175)FPGA门控时钟技术
  • (cos^2 X)的定积分,求积分 ∫sin^2(x) dx
  • (C语言)fgets与fputs函数详解
  • (TOJ2804)Even? Odd?
  • (二)什么是Vite——Vite 和 Webpack 区别(冷启动)
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (官网安装) 基于CentOS 7安装MangoDB和MangoDB Shell
  • (全注解开发)学习Spring-MVC的第三天
  • (三分钟了解debug)SLAM研究方向-Debug总结
  • (四)汇编语言——简单程序
  • (一)pytest自动化测试框架之生成测试报告(mac系统)
  • (已解决)什么是vue导航守卫
  • (转)Linux整合apache和tomcat构建Web服务器