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