前端Pako.js 压缩解压库 与 Java 的 zlib 压缩与解压 的互通实现
工具介绍:
pako.js 前端压缩解压的库(包含 zlib 和gzip 两种实现,这里只介绍 zlib)
pako 2.0.4 API documentation
Java8+ 原生支持 zlib 和 gzip
业务场景
因为数据太大,网络环境不可控。故前端需要将数据 A 先压缩 变为 a,然后才将 a 发送到 Java 服务器端后处理或存储。
后端 Java 也可以调取存储的压缩结果进行解压,重新发往前端
这里介绍 pako.js 的zlib 接口 与 Java 的互通。
首先是前端:
由于 pako.js 库的压缩后的结果 是 Uint8Array
Uint8Array 数组类型表示一个8位无符号整型数组,创建时内容被初始化为0。创建完后,可以以对象的方式或使用数组下标索引的方式引用数组中的元素。
由于 它的 toString() 不包含特殊字符,故可以被 http 直接传输 (无需 转换为 base64)。
故发送到服务端的串 ,大致形式为 : 123,12,99,1,34
然后是 Java 的服务端
Java 原生支持 zlib 压缩和解压方式,百度上很多例子。这里不赘述。
略微麻烦的地方在于,
接受端:前端发送过来的上述的那种格式,需要转变为 java 的压缩解压接口的参数的固定格式。
发送端:发送给前端的数据(显然是 zlib 压缩后的数据),同样需要转换为 上述格式。
这里强调下,为什么前端解压后端的压缩数据时,一定要让后端发送给前端的数据格式,去和前端库发送给后端的数据格式保持一致呢?(不要吐槽我的逗号断句,这句实在太绕了)
因为 在前后端分离的开发模式下,对于前端开发人员,是不应该关注后端的技术实现。显然,后端努力去迎合 前端库的特有数据格式(因伟大而落泪)。
下面直接贴上 代码:
前端代码:(用 jquery 库)
// 首先你需要引入 pako.js 库,这里就不贴了
// 这里要压缩的内容
let content = “我是张三 **@*¥)*¥*)@#*#*@+—— ~kdfkda55d4 fd”;
// 前端压缩
let clientData = pako.deflate(content);
// 变成 串
clientData = clientData.toString()
console.log(“client 压缩后>>”,clientData)
$.post(“http://localhost:10003/demo/test2CompresAndUncompress”,{
data:clientData
},function(data){
console.log(“接受 server 压缩原文:”,data);
let b = data.split(‘,’).map(function (x) { return parseInt(x); });
// console.log(“client 解压后split:”,b);
let c = pako.inflate(b,{to :“string”});
// 完毕 撒花
console.log(“client 解压后:”,c);
});
后端代码(这里用的是 springboot 框架):
Controller:
@RequestMapping(value = “/test2CompresAndUncompress”)
@ResponseBody
public String test2CompresAndUncompress(@RequestParam String data) throws IOException {
System.out.println(“接収 client 原文<<”+data);
/**
* 将数字的字符串 转为 byte[]
*/
byte[] clientBytes = PakoUtil.receive(data);
byte[] bytes = ZlibUtil.decompress(clientBytes);
System.out.println(“server 解压后<<”+new String(bytes));
//重新压缩,打算向服务器 发送 压缩后的代码
byte[] encodingStr = ZlibUtil.compress(bytes);
System.out.println(“我自己尝试解压后1>>”+new String(encodingStr));
System.out.println(“我自己尝试解压后2>>”+new String(ZlibUtil.decompress(encodingStr)));
return PakoUtil.send(encodingStr);
}
上面代码涉及的工具类(ZlibUtil.java 和 PakoUtil.java):
ZlibUtil.java:
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
import java.util.zip.Deflater;
import java.util.zip.DeflaterOutputStream;
import java.util.zip.Inflater;
import java.util.zip.InflaterInputStream;
/**
* zlib 压缩算法
* java 就是牛,原生支持
* @author jx
*
*/
public class ZlibUtil {
/**
* 压缩
*
* @param data
* 待压缩数据
* @return byte[] 压缩后的数据
*/
public static byte[] compress(byte[] data) {
byte[] output = new byte[0];
Deflater compresser = new Deflater();
compresser.reset();
compresser.setInput(data);
compresser.finish();
ByteArrayOutputStream bos = new ByteArrayOutputStream(data.length);
try {
byte[] buf = new byte[1024];
while (!compresser.finished()) {
int i = compresser.deflate(buf);
bos.write(buf, 0, i);
}
output = bos.toByteArray();
} catch (Exception e) {
output = data;
e.printStackTrace();
} finally {
try {
bos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
compresser.end();
return output;
}
/**
* 压缩
*
* @param data
* 待压缩数据
*
* @param os
* 输出流
*/
public static void compress(byte[] data, OutputStream os) {
DeflaterOutputStream dos = new DeflaterOutputStream(os);
try {
dos.write(data, 0, data.length);
dos.finish();
dos.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 解压缩
*
* @param data
* 待压缩的数据
* @return byte[] 解压缩后的数据
*/
public static byte[] decompress(byte[] data) {
byte[] output = new byte[0];
Inflater decompresser = new Inflater();
decompresser.reset();
decompresser.setInput(data);
ByteArrayOutputStream o = new ByteArrayOutputStream(data.length);
try {
byte[] buf = new byte[1024];
while (!decompresser.finished()) {
int i = decompresser.inflate(buf);
o.write(buf, 0, i);
}
output = o.toByteArray();
} catch (Exception e) {
output = data;
e.printStackTrace();
} finally {
try {
o.close();
} catch (IOException e) {
e.printStackTrace();
}
}
decompresser.end();
return output;
}
/**
* 解压缩
*
* @param is
* 输入流
* @return byte[] 解压缩后的数据
*/
public static byte[] decompress(InputStream is) {
InflaterInputStream iis = new InflaterInputStream(is);
ByteArrayOutputStream o = new ByteArrayOutputStream(1024);
try {
int i = 1024;
byte[] buf = new byte[i];
while ((i = iis.read(buf, 0, i)) > 0) {
o.write(buf, 0, i);
}
} catch (IOException e) {
e.printStackTrace();
}
return o.toByteArray();
}
public static void main(String[] args) throws UnsupportedEncodingException {
String data = “aadfklafdafla我是中国人的啦啦啦”;
System.out.println(“原文:”+data);
// 报错
// String a = Base64Util.encode(ZlibUtil.compress(data.getBytes()));
//
// String b = new String(ZlibUtil.decompress(Base64Util.decode(a)));
byte[] a = ZlibUtil.compress(data.getBytes(“UTF-8”));
System.out.println(“>>”+Arrays.toString(a));
byte[] b = ZlibUtil.decompress(a);
// System.out.println(“压缩后:”+a);
System.out.println(“jieya后:”+new String(b));
}
void a(){
// try {
// // Encode a String into bytes
// String inputString = “Pehla nasha Pehla khumaar Naya pyaar hai naya intezaar Kar loon main kya apna haal Aye dil-e-bekaraar Mere dil-e-bekaraar Tu hi bata Pehla nasha Pehla khumaar Udta hi firoon in hawaon mein kahin Ya main jhool jaoon in ghataon mein kahin Udta hi firoon in hawaon mein kahin Ya main jhool jaoon in ghataon mein kahin Ek kar doon aasmaan zameen Kaho yaaron kya karoon kya nahin Pehla nasha Pehla khumaar Naya pyaar hai naya intezaar Kar loon main kya apna haal Aye dil-e-bekaraar Mere dil-e-bekaraar Tu hi bata Pehla nasha Pehla khumaar Usne baat ki kuchh aise dhang se Sapne de gaya vo hazaaron range ke Usne baat ki kuchh aise dhang se Sapne de gaya vo hazaaron range ke Reh jaoon jaise main haar ke Aur choome vo mujhe pyaar se Pehla nasha Pehla khumaar Naya pyaar hai naya intezaar Kar loon main kya apna haal Aye dil-e-bekaraar Mere dil-e-bekaraar”;
// byte[] input = inputString.getBytes(“UTF-8”);
// // Compress the bytes
// byte[] output1 = new byte[input.length];
// Deflater compresser = new Deflater();
// compresser.setInput(input);
// compresser.finish();
// int compressedDataLength = compresser.deflate(output1);
// compresser.end();
// String str = Base64.encode(output1);
// System.out.println(“Deflated String:” + str);
// byte[] output2 = Base64.decode(str);
// // Decompress the bytes
// Inflater decompresser = new Inflater();
// decompresser.setInput(output2);
// byte[] result = str.getBytes();
// int resultLength = decompresser.inflate(result);
// decompresser.end();
// // Decode the bytes into a String
// String outputString = new String(result, 0, resultLength, “UTF-8”);
// System.out.println(“Deflated String:” + outputString);
// } catch (UnsupportedEncodingException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (DataFormatException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
//
}
}
PakoUtil.java:
/**
* 针对 前端的 pako.js 压缩和解压插件 的发送、推送的数据处理
* 目标是使和Java 的zlib 压缩解压交互方便
* @see http://nodeca.github.io/pako/#inflate
* @author jx
*
*/
public class PakoUtil {
/**
* 从 Pako.js 中接受的数据
* @param arrStr 形如: 123,2,09,
* 字符串是由无符号整数构成,逗号分隔
* @return
*/
public static byte[] receive(String arrInt){
/**
* 将数字字符串 -> byte[]
*/
String[] a = arrInt.split(“,”);
byte[] clientBytes = new byte[a.length];
int i = 0;
for (String e : a) {
clientBytes[i] = Integer.valueOf(e).byteValue();
i++;
}
return clientBytes;
}
/**
* 发送给 Pako 的数据格式
* @param bytes 服务端生成的字节数组
* @return String 发送给 pako.js 的数据格式
*/
public static String send(byte[] bytes) {
String[] ints = new String[bytes.length];
int j=0;
for(byte e:bytes) {
int t = e;
if(t<0) {
t = 256+t;
}
ints[j++] = String.valueOf(t);
}
return String.join(“,”, ints);
}
}
原文链接:https://blog.csdn.net/rainyspring4540/article/details/121383490
相关文章:
前端Pako.js 压缩解压库 与 Java 的 zlib 压缩与解压 的互通实现
工具介绍: pako.js 前端压缩解压的库(包含 zlib 和gzip 两种实现,这里只介绍 zlib) pako 2.0.4 API documentation Java8 原生支持 zlib 和 gzip 业务场景 因为数据太大,网络环境不可控。故前端需要将数据 A 先压缩…...
unity 打包出来的所有执行文件内容打包成一个exe程序
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、使用Enigma Virtual Box1.下载安装包(根据需要32位还是64位。一般是64位)2.改个语言,方便使用(改了后重启才…...
华为管理变革之道:组织文化与活力
目录 企业文化是什么? 为什么活下去是华为的文化? 活下来,是华为公司的最低纲领,也是华为公司的最高纲领! 资源终会枯竭,唯有文化才能生生不息 企业文化之一:以客户为中心 企业文化之二&a…...
仿闲鱼的二手交易小程序软件开发闲置物品回收平台系统源码
市场前景 闲置物品交易软件的市场前景广阔,主要基于以下几个方面的因素: 环保意识提升:随着人们环保意识的增强,越来越多的人开始关注资源的循环利用,闲置物品交易因此受到了广泛的关注。消费升级与时尚节奏加快&…...
PostgreSQL CRUD 操作指南
PostgreSQL CRUD 操作指南 连接数据库 -- 连接到特定数据库 psql -U postgres -d xianxia-- 列出所有数据库 \l-- 切换数据库 \c xianxia-- 列出所有表 \dt-- 查看表结构 \d table_name基本 CRUD 操作 CREATE(创建) -- 创建新表 CREATE TABLE users …...
4X4规模S盒分量布尔函数计算工具(附各大常见分组加密算法S盒查找表和其对应分量布尔函数截图)
文章结尾有S盒分量布尔函数计算工具下载地址 Serpent {0x3,0x8,0xF,0x1,0xA,0x6,0x5,0xB,0xE,0xD,0x4,0x2,0x7,0x0,0x9,0xC} LBlock {0xE,0x9,0xF,0x0,0xD,0x4,0xA,0xB,0x1,0x2,0x8,0x3,0x7,0x6,0xC,0x5} GOST {0x4,0xA,0x9,0x2,0xD,0x8,0x0,0xE,0x6,0xB,0x1,0xC,0x7,0xF,0x5,0…...
模拟——郑益慧_笔记1_绪论
B站视频链接 模电是数电的基础;参考书: 模拟电子技术基础(第四版)华成英、童诗白主编,高等教育出版社;电子技术基础 模拟部分 康华光主编,高等教育出版社; 电子技术的发展史 电子…...
金融租赁系统的发展与全球化战略实施探讨
内容概要 金融租赁系统的演变并非一帆风顺,像一场跌宕起伏的电影。首先,咱们得看看它的起源及现状。随着经济的快速发展,金融租赁逐渐作为一种灵活的融资手段崭露头角。在中国市场中,企业对设备和技术更新换代的需求日益迫切&…...
vue3入门教程:计算属性
计算属性的基本用法 计算属性是通过computed函数创建的,它接受一个getter函数作为参数,并返回一个只读的响应式ref对象。该ref对象通过.value属性暴露getter函数的返回值。 <template><div><p>原始数据: {{ count }}</p><p…...
Docker怎么关闭容器开机自启,批量好几个容器一起操作?
环境: WSL2 docker v25 问题描述: Docker怎么关闭容器开机自启,批量好几个容器一起操作? 解决方案: 在 Docker 中,您可以使用多种方法来关闭容器并配置它们是否在系统启动时自动启动。以下是具体步骤和…...
shell脚本(全)
shell脚本概述 第一个shell脚本 shell注释 shell变量 shell位置参数 shell字符串 shell内置命令 shell命令替换 输出 流程控制IF export命令 退出脚本 运行Shell脚本 实例导航 shell脚本概述 在说什么是shell脚本之前,先说说什么是shell。 从程序员的…...
华为手机建议使用adb卸载的app
按需求自行卸载 echo 卸载智慧搜索 adb shell pm uninstall -k --user 0 com.huawei.search echo 卸载智慧助手 adb shell pm uninstall -k --user 0 com.huawei.intelligent echo 卸载讯飞语音引擎 adb shell pm uninstall -k --user 0 com.iflytek.speechsuite echo 卸载快应…...
论文解读 | EMNLP2024 一种用于大语言模型版本更新的学习率路径切换训练范式
点击蓝字 关注我们 AI TIME欢迎每一位AI爱好者的加入! 点击 阅读原文 观看作者讲解回放! 作者简介 王志豪,厦门大学博士生 刘诗雨,厦门大学硕士生 内容简介 新数据的不断涌现使版本更新成为大型语言模型(LLMsÿ…...
Java基础(Json和Java对象)
定义好实体类 package com.pyb.pojo; /*** version 1.0* Author 彭彦彬* Date 2024/12/24 20:47* 注释*/ public class Person {private String username;private String password; public Person() {} public Person(String username, String password) {this.username…...
Linux 中检查 Apache Web Server (httpd) 正常运行时间的 4 种方法
注:机翻,未校。 4 Ways To Check Uptime of Apache Web Server (httpd) on Linux November 28, 2019 by Magesh Maruthamuthu We all know about the purpose of uptime command in Linux. 我们都知道 Linux 中 uptime 命令的目的。 It is used to c…...
Linux驱动开发--字符设备驱动开发
一、概述 字符设备是 Linux 驱动中最基本的一类设备驱动,字符设备就是一个一个字节,按照字节 流进行读写操作的设备,读写数据是分先后顺序的。比如我们最常见的点灯、按键、 IIC、 SPI, LCD 等等都是字符设备,这些设备的驱动就叫做字符设备驱动。 Linux 应用程序对驱动程…...
MarkItDown的使用(将Word、Excel、PDF等转换为Markdown格式)
MarkItDown的使用(将Word、Excel、PDF等转换为Markdown格式) 本文目录: 零、时光宝盒🌻 一、简介 二、安装 三、使用方法 3.1、使用命令行形式 3.2、用 Python 调用 四、总结 五、参考资料 零、时光宝盒🌻 &a…...
一文彻底拿捏DevEco Studio的使用小技巧
程序员Feri一名12年的程序员,做过开发带过团队创过业,擅长Java相关开发、鸿蒙开发、人工智能等,专注于程序员搞钱那点儿事,希望在搞钱的路上有你相伴!君志所向,一往无前! 0.安装DevEco Studio DevEco Studio面向HarmonyOS应用及元服务开发者提供的集成开…...
R9000P键盘失灵解决办法
问题描述 突然,就是很突然,我买的R9000P 2024不到三个月,键盘突然都不能用了,是所有键盘按键都无效的那种。(可以使用外接键盘) 解决办法 我本科室友说的好哈,全坏全没坏。 (该解…...
【Linux之Shell脚本实战】编写简单计算器shell脚本
【Linux之Shell脚本实战】编写简单计算器shell脚本 一、Shell脚本介绍1.1 Shell脚本简介1.2 Shell脚本特点二、脚本要求三、检查本地环境3.1 本地环境规划3.2 检查本地系统3.3 检查系统内核版本四、编写脚本4.1 脚本内容4.2 脚本分析整体逻辑各功能实现使用方法4.3 执行效果五、…...
从零开始打造 OpenSTLinux 6.6 Yocto 系统(基于STM32CubeMX)(九)
设备树移植 和uboot设备树修改的内容同步到kernel将设备树stm32mp157d-stm32mp157daa1-mx.dts复制到内核源码目录下 源码修改及编译 修改arch/arm/boot/dts/st/Makefile,新增设备树编译 stm32mp157f-ev1-m4-examples.dtb \stm32mp157d-stm32mp157daa1-mx.dtb修改…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
七、数据库的完整性
七、数据库的完整性 主要内容 7.1 数据库的完整性概述 7.2 实体完整性 7.3 参照完整性 7.4 用户定义的完整性 7.5 触发器 7.6 SQL Server中数据库完整性的实现 7.7 小结 7.1 数据库的完整性概述 数据库完整性的含义 正确性 指数据的合法性 有效性 指数据是否属于所定…...
【JVM面试篇】高频八股汇总——类加载和类加载器
目录 1. 讲一下类加载过程? 2. Java创建对象的过程? 3. 对象的生命周期? 4. 类加载器有哪些? 5. 双亲委派模型的作用(好处)? 6. 讲一下类的加载和双亲委派原则? 7. 双亲委派模…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
【Elasticsearch】Elasticsearch 在大数据生态圈的地位 实践经验
Elasticsearch 在大数据生态圈的地位 & 实践经验 1.Elasticsearch 的优势1.1 Elasticsearch 解决的核心问题1.1.1 传统方案的短板1.1.2 Elasticsearch 的解决方案 1.2 与大数据组件的对比优势1.3 关键优势技术支撑1.4 Elasticsearch 的竞品1.4.1 全文搜索领域1.4.2 日志分析…...
C++实现分布式网络通信框架RPC(2)——rpc发布端
有了上篇文章的项目的基本知识的了解,现在我们就开始构建项目。 目录 一、构建工程目录 二、本地服务发布成RPC服务 2.1理解RPC发布 2.2实现 三、Mprpc框架的基础类设计 3.1框架的初始化类 MprpcApplication 代码实现 3.2读取配置文件类 MprpcConfig 代码实现…...
AxureRP-Pro-Beta-Setup_114413.exe (6.0.0.2887)
Name:3ddown Serial:FiCGEezgdGoYILo8U/2MFyCWj0jZoJc/sziRRj2/ENvtEq7w1RH97k5MWctqVHA 注册用户名:Axure 序列号:8t3Yk/zu4cX601/seX6wBZgYRVj/lkC2PICCdO4sFKCCLx8mcCnccoylVb40lP...
【免费数据】2005-2019年我国272个地级市的旅游竞争力多指标数据(33个指标)
旅游业是一个城市的重要产业构成。旅游竞争力是一个城市竞争力的重要构成部分。一个城市的旅游竞争力反映了其在旅游市场竞争中的比较优势。 今日我们分享的是2005-2019年我国272个地级市的旅游竞争力多指标数据!该数据集源自2025年4月发表于《地理学报》的论文成果…...
链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...
