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
相关产品推荐
相关产品推荐

