You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何使用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

火山引擎 最新活动