如何在Java中反序列化Thrift对象字符串?
解决Thrift对象toString字符串反序列化问题
你的报错原因很明确:你使用的TBinaryProtocol是用于解析Thrift二进制序列化数据的,但你手里的字符串是Thrift对象toString()方法输出的人类可读文本格式,和Thrift官方的二进制序列化格式完全不兼容,所以TDeserializer无法识别,抛出读取错误。
下面提供两种可行的解决方式:
方式一:手动解析toString格式字符串
因为这个字符串是固定的结构化格式,你可以直接拆分字符串并给对象字段赋值:
String objStr = "MyObject(id:1, name:abc xyz, flag:true)"; // 提取括号内的字段内容 String fieldContent = objStr.substring(objStr.indexOf('(') + 1, objStr.lastIndexOf(')')); // 分割每个字段(注意用", "作为分隔符,避免value中的逗号干扰) String[] fieldPairs = fieldContent.split(", "); MyObject myObj = new MyObject(); for (String pair : fieldPairs) { // 按":"拆分键值对,限制拆分次数为2,避免value中包含冒号的情况 String[] keyValue = pair.split(":", 2); String key = keyValue[0]; String value = keyValue[1]; switch (key) { case "id": myObj.setId(Integer.parseInt(value)); break; case "name": myObj.setName(value); break; case "flag": myObj.setFlag(Boolean.parseBoolean(value)); break; // 若有其他字段,继续补充case分支 } }
注意:如果字段值中包含
,或者:,上述简单拆分会失效,此时需要用更严谨的正则表达式来匹配字段,比如用正则(\w+):([^,]+)(?=, |$)来提取键值对。
方式二:改用Thrift文本协议序列化/反序列化(推荐)
如果这个字符串是你自己生成的,不要用对象的toString()方法,改用Thrift官方的文本协议(比如TJSONProtocol)来序列化对象,这样后续可以直接用对应协议反序列化,无需手动解析:
序列化(生成标准Thrift文本格式)
// 创建并初始化对象 MyObject sourceObj = new MyObject(); sourceObj.setId(1); sourceObj.setName("abc xyz"); sourceObj.setFlag(true); // 使用TJSONProtocol序列化 TProtocolFactory jsonProtocolFactory = new TJSONProtocol.Factory(); TSerializer serializer = new TSerializer(jsonProtocolFactory); String serializedStr = serializer.toString(sourceObj);
反序列化
// 用相同的TJSONProtocol反序列化 TProtocolFactory jsonProtocolFactory = new TJSONProtocol.Factory(); TDeserializer deserializer = new TDeserializer(jsonProtocolFactory); MyObject myObj = new MyObject(); deserializer.deserialize(myObj, serializedStr.getBytes(StandardCharsets.UTF_8));
这种方式完全遵循Thrift的序列化规范,不会出现格式不兼容的问题,也无需处理复杂的字符串解析逻辑。
内容的提问来源于stack exchange,提问作者charmander
相关产品推荐
相关产品推荐

