springboot集成gzip和zip數(shù)據(jù)壓縮傳輸(適用大數(shù)據(jù)信息傳輸)
1、背景
在查詢數(shù)據(jù)庫信息的時(shí)候,由于數(shù)據(jù)庫信息返回?cái)?shù)據(jù)條數(shù)較多,數(shù)據(jù)從服務(wù)器端傳至客戶端耗費(fèi)大量時(shí)間,導(dǎo)致查詢數(shù)據(jù)變慢。
2、方案思路
1)、從查詢sql上入手,進(jìn)行sql優(yōu)化;
2)、從業(yè)務(wù)層面優(yōu)化,復(fù)雜接口拆分成多個(gè)接口,避免大量數(shù)據(jù)堆積返回(視業(yè)務(wù)需求而定);
3)、對(duì)返回的大數(shù)據(jù)信息進(jìn)行數(shù)據(jù)壓縮。(本文要點(diǎn))

3、壓縮數(shù)據(jù)方案
1)、gzip壓縮
2)、zip壓縮
4、具體實(shí)現(xiàn)
(1)、gzip壓縮方案
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 數(shù)據(jù)流
* @return 壓縮數(shù)據(jù)流
* @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 需要壓縮數(shù)據(jù)信息
* @return 壓縮數(shù)據(jù)流
* @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 欲解壓數(shù)據(jù)流
* @return 原數(shù)據(jù)流
* @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 欲解壓數(shù)據(jù)字符串
* @return 原數(shù)據(jù)
* @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);
}
}數(shù)據(jù)壓縮
@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");
// 調(diào)用數(shù)據(jù)庫獲取數(shù)據(jù)
Map<String, Object> resMap = testMapper.findInfo(sqlStr);
String dataStr = JSONObject.toJSONString(resMap);
// 開始?jí)嚎s數(shù)據(jù)
byte[] compress1 = gzipUtils.compress(dataStr);
String FileBuf = Base64.getEncoder().encodeToString(compress1);
return new JSONBeansResponse<>(FileBuf);
}
return new JSONBeansResponse<>(new ArrayList<>(0));
}數(shù)據(jù)解壓
@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));
}遇到問題
解壓時(shí)候報(bào)錯(cuò):java.util.zip.ZipException: Not in GZIP format
解決方案:在轉(zhuǎn)換為字符串時(shí),一定要使用ISO-8859-1這樣的單字節(jié)編碼

(2)、zip壓縮方案
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 原數(shù)據(jù)流
* @return 壓縮后的數(shù)據(jù)流
* @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 原數(shù)據(jù)字符串
* @return 壓縮后的數(shù)據(jù)流
* @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 壓縮后的數(shù)據(jù)流
* @return 原數(shù)據(jù)的數(shù)據(jù)流
* @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 原數(shù)據(jù)字符串
* @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);
}
}zip使用
@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);
// 開始?jí)嚎s數(shù)據(jù)
byte[] compress1 = zipUtils.compress(dataStr);
String FileBuf = Base64.getEncoder().encodeToString(compress1);
// 開始解壓數(shù)據(jù)
String s = zipUtils.uncompress(FileBuf);
List<Map> arrayLists = JSONObject.parseArray(s, Map.class);
return new JSONBeansResponse<>(arrayLists);
}5、總結(jié)
在大數(shù)據(jù)量的傳輸中,壓縮數(shù)據(jù)后進(jìn)行傳輸可以一定程度的解決速度問題。
zip和gzip的壓縮率測(cè)試過幾次大概在5-6倍大小左右。
到此這篇關(guān)于springboot集成gzip和zip數(shù)據(jù)壓縮傳輸(適用大數(shù)據(jù)信息傳輸)的文章就介紹到這了,更多相關(guān)springboot gzip和zip數(shù)據(jù)壓縮傳輸內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Mybatis-Plus實(shí)現(xiàn)自動(dòng)生成代碼的操作步驟
AutoGenerator 是 MyBatis-Plus 的代碼生成器,通過 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各個(gè)模塊的代碼,極大的提升了開發(fā)效率,本文將給大家介紹Mybatis-Plus實(shí)現(xiàn)自動(dòng)生成代碼的操作步驟2023-10-10
Spring?JPA使用CriteriaBuilder動(dòng)態(tài)構(gòu)造查詢方式
這篇文章主要介紹了Spring?JPA使用CriteriaBuilder動(dòng)態(tài)構(gòu)造查詢方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12
spring boot下mybatis配置雙數(shù)據(jù)源的實(shí)例
這篇文章主要介紹了spring boot下mybatis配置雙數(shù)據(jù)源的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
IntelliJ IDEA2019 安裝lombok的實(shí)現(xiàn)
這篇文章主要介紹了IntelliJ IDEA2019 安裝lombok的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-10-10
java設(shè)計(jì)模式之建造者模式學(xué)習(xí)
建造者模式(Builder Pattern)主要用于“分步驟構(gòu)建一個(gè)復(fù)雜的對(duì)象”,在這其中“分步驟”是一個(gè)穩(wěn)定的算法,下面給出了詳細(xì)的示例2014-01-01
java Split 實(shí)現(xiàn)去除一個(gè)空格和多個(gè)空格
這篇文章主要介紹了java Split 實(shí)現(xiàn)去除一個(gè)空格和多個(gè)空格,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-10-10
Java微信公眾平臺(tái)開發(fā)(5) 文本及圖文消息回復(fù)的實(shí)現(xiàn)
這篇文章主要為大家詳細(xì)介紹了Java微信公眾平臺(tái)開發(fā)第五步,回文本及圖文消息回復(fù)的實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2017-04-04

