You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中字符串存储解析Protocol Buffers对象时解析异常求助

在Java中可靠存储和解析Protocol Buffers数据的方案

问题原因

Protobuf的二进制数据(ByteString)是原始字节流,并非合法的UTF-8字符序列。用UTF-8编码将其转为字符串时,不兼容的字节会被替换为占位符,再转回字节流时数据已损坏,导致解析后的字段值错误。

ISO_8859_1能暂时正常工作,是因为它是单字节编码,每个字节对应唯一字符,转字符串时不会丢失字节。但这种方式存在隐患:生成的字符串可能包含不可打印控制字符,在存储(如数据库文本字段)或传输(如HTTP文本参数)时可能被截断、过滤或乱码,无法保证跨场景的可靠性。

可靠解决方案:Base64编码

将Protobuf二进制数据转为Base64字符串是通用且安全的方案,Base64用64个可打印字符(字母、数字、+、/)表示二进制数据,无编码损失,跨平台跨语言兼容,完全避免字节损坏问题。

示例代码

import java.util.Base64;
import com.google.protobuf.InvalidProtocolBufferException;

public static void test2() throws InvalidProtocolBufferException {
    CrcCertInfoRequest data = CrcCertInfoRequest.newBuilder().setCompanyType(222).build();
    
    // 将Protobuf数据转为Base64字符串
    String base64Str = Base64.getEncoder().encodeToString(data.toByteArray());
    
    // 从Base64字符串解析回Protobuf对象
    byte[] decodedBytes = Base64.getDecoder().decode(base64Str);
    CrcCertInfoRequest parsedData = CrcCertInfoRequest.parseFrom(decodedBytes);

    String json = ObjectMapperUtils.toJSON(data);
    System.out.println("base64Str=" + base64Str.length() + " json=" + json.length());

    System.out.println(ObjectMapperUtils.toJSON(parsedData));
    System.out.println(ObjectMapperUtils.toJSON(ObjectMapperUtils.fromJSON(json, CrcCertInfoRequest.class)));
}

方案说明

  • Base64编码后的字符串仅包含可打印字符,适合存储到文本类型字段、作为URL参数或在文本协议中传输。
  • JDK 8及以上自带java.util.Base64工具类,无需额外依赖。
  • 所有主流编程语言都支持Base64编解码,确保跨系统交互的兼容性。

内容的提问来源于stack exchange,提问作者bowen zhang

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 02:10:31