如何使用Gzip压缩与解压Java POJO对象?
Client POJO 的 Gzip 压缩与解压实现方案
要搞定Client POJO的Gzip压缩和解压,核心逻辑其实是先把对象转换成可传输的字节数组(也就是序列化),做完Gzip的压缩/解压后,再把字节数组还原回Client对象(反序列化)。下面我给你两种常用的实现方案,你可以根据场景选择:
方案一:Java原生序列化实现
这种方式依赖Java自带的序列化机制,需要让Client类实现Serializable接口,确保对象可以被序列化和反序列化。
第一步:修改Client类
import java.io.Serializable; class Client implements Serializable { // 显式定义序列化版本号,避免序列化兼容问题 private static final long serialVersionUID = 1L; public String name; public String location; // Getter和Setter方法 public String getName() { return name; } public void setName(String name) { this.name = name; } public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } }
第二步:实现压缩方法
把Client对象序列化后进行Gzip压缩,最后转成URL编码的字符串方便传输:
import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectOutputStream; import java.net.URLEncoder; import java.util.zip.GZIPOutputStream; public static String compressClient(Client cc) { if (cc == null) { return null; } try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); GZIPOutputStream gzipOut = new GZIPOutputStream(byteOut); ObjectOutputStream objOut = new ObjectOutputStream(gzipOut)) { // 序列化Client对象到输出流 objOut.writeObject(cc); objOut.flush(); gzipOut.finish(); // 完成Gzip压缩 // 转成ISO-8859-1编码(单字节编码,完整保存字节信息)后URL编码 return URLEncoder.encode(byteOut.toString("ISO-8859-1"), "UTF-8"); } catch (IOException e) { e.printStackTrace(); return null; } }
第三步:实现解压方法
反向操作:先URL解码,再解Gzip,最后反序列化为Client对象:
import java.io.ByteArrayInputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.net.URLDecoder; import java.util.zip.GZIPInputStream; public static Client decompressClient(String compressedStr) { if (compressedStr == null || compressedStr.isEmpty()) { return null; } try { // 先URL解码,再转成原始字节数组 String decodedStr = URLDecoder.decode(compressedStr, "UTF-8"); byte[] compressedBytes = decodedStr.getBytes("ISO-8859-1"); try (ByteArrayInputStream byteIn = new ByteArrayInputStream(compressedBytes); GZIPInputStream gzipIn = new GZIPInputStream(byteIn); ObjectInputStream objIn = new ObjectInputStream(gzipIn)) { // 反序列化得到Client对象 return (Client) objIn.readObject(); } } catch (IOException | ClassNotFoundException e) { e.printStackTrace(); return null; } }
方案二:JSON序列化实现(跨语言友好)
如果需要跨语言传输,或者不想依赖Java原生序列化,推荐用JSON序列化(比如Jackson库),这种方式不需要Client实现Serializable,灵活性更高。
第一步:引入Jackson依赖(Maven示例)
如果用Maven,需要在pom.xml中添加依赖:
<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.15.2</version> <!-- 用最新稳定版即可 --> </dependency>
第二步:实现压缩方法
把Client转成JSON字节数组后进行Gzip压缩:
import com.fasterxml.jackson.databind.ObjectMapper; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URLEncoder; import java.util.zip.GZIPOutputStream; public static String compressClientWithJson(Client cc) { if (cc == null) { return null; } ObjectMapper mapper = new ObjectMapper(); try (ByteArrayOutputStream byteOut = new ByteArrayOutputStream(); GZIPOutputStream gzipOut = new GZIPOutputStream(byteOut)) { // 把Client对象转成JSON字节数组 byte[] jsonBytes = mapper.writeValueAsBytes(cc); gzipOut.write(jsonBytes); gzipOut.finish(); return URLEncoder.encode(byteOut.toString("ISO-8859-1"), "UTF-8"); } catch (IOException e) { e.printStackTrace(); return null; } }
第三步:实现解压方法
解Gzip后把JSON字节数组转回Client对象:
import com.fasterxml.jackson.databind.ObjectMapper; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.net.URLDecoder; import java.util.zip.GZIPInputStream; public static Client decompressClientWithJson(String compressedStr) { if (compressedStr == null || compressedStr.isEmpty()) { return null; } ObjectMapper mapper = new ObjectMapper(); try { String decodedStr = URLDecoder.decode(compressedStr, "UTF-8"); byte[] compressedBytes = decodedStr.getBytes("ISO-8859-1"); try (ByteArrayInputStream byteIn = new ByteArrayInputStream(compressedBytes); GZIPInputStream gzipIn = new GZIPInputStream(byteIn); ByteArrayOutputStream byteOut = new ByteArrayOutputStream()) { byte[] buffer = new byte[1024]; int len; // 读取解压缩后的字节到输出流 while ((len = gzipIn.read(buffer)) != -1) { byteOut.write(buffer, 0, len); } // 把JSON字节数组转成Client对象 return mapper.readValue(byteOut.toByteArray(), Client.class); } } catch (IOException e) { e.printStackTrace(); return null; } }
注意事项
- 原生序列化方案:必须保证Client类实现
Serializable,且serialVersionUID最好显式定义,避免类结构变化导致反序列化失败。 - JSON序列化方案:需要引入Jackson(或其他JSON库,比如Gson),但跨语言兼容性更好,即使其他语言(比如Python、Go)也能解析生成的JSON。
- 编码处理:用
ISO-8859-1是因为它是单字节编码,能完整保留字节数组的原始内容,再做URL编码是为了方便在HTTP参数或URL中传输,避免特殊字符乱码。
内容的提问来源于stack exchange,提问作者user10386436




