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

将JSON字符串转为Thrift对象时遇TProtocolException错误求助

问题描述

我有一个JSON字符串,想要将其转换为Thrift对象。Thrift定义如下:

struct Person {
    1: optional string name;
}

我的C++代码如下:

#include <thrift/TBase.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/protocol/TJSONProtocol.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/transport/TTransportUtils.h>

#include <cstring>

#include "Person_types.h"

int main() {
    std::string s = R"({"name": "alice"})";

    auto transport = std::make_shared<apache::thrift::transport::TMemoryBuffer>((uint8_t *)s.data(), s.length());
    auto protocol_factory = std::make_shared<apache::thrift::protocol::TJSONProtocolFactory>();
    auto protocol = protocol_factory->getProtocol(transport);

    Person obj;
    obj.read(protocol.get());
}

运行时遇到错误,错误信息如下:

terminate called after throwing an instance of 'apache::thrift::protocol::TProtocolException'
  what():  Expected '"'; got 'n'.
Aborted (core dumped)

使用的Thrift版本为0.12.0,请求解决该问题。

解决方案

Thrift的TJSONProtocol不支持标准JSON解析,它采用Thrift自定义的JSON格式,要求根对象的键必须是Thrift字段的整数ID,而非字段名。你传入的标准JSON用了字段名name,不符合协议要求,因此报错。

提供两种解决方法:

方法一:改用Thrift自定义JSON格式

将输入JSON改为以字段ID作为键的格式:

std::string s = R"({"1": "alice"})";

修改后即可正常解析。

方法二:使用TSimpleJSONProtocol(推荐)

Thrift 0.11.0及以上版本提供了TSimpleJSONProtocol,支持解析标准JSON(用字段名而非ID)。修改步骤如下:

  1. 添加头文件引入:
#include <thrift/protocol/TSimpleJSONProtocol.h>
  1. 替换协议工厂:
// 替换原有的TJSONProtocolFactory
auto protocol_factory = std::make_shared<apache::thrift::protocol::TSimpleJSONProtocolFactory>();

修改后的完整代码:

#include <thrift/TBase.h>
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/protocol/TJSONProtocol.h>
#include <thrift/protocol/TSimpleJSONProtocol.h>
#include <thrift/transport/TBufferTransports.h>
#include <thrift/transport/TTransportUtils.h>

#include <cstring>

#include "Person_types.h"

int main() {
    std::string s = R"({"name": "alice"})";

    auto transport = std::make_shared<apache::thrift::transport::TMemoryBuffer>((uint8_t *)s.data(), s.length());
    auto protocol_factory = std::make_shared<apache::thrift::protocol::TSimpleJSONProtocolFactory>();
    auto protocol = protocol_factory->getProtocol(transport);

    Person obj;
    obj.read(protocol.get());
}

此方法无需修改输入JSON格式,直接兼容标准JSON,更符合需求。

内容的提问来源于stack exchange,提问作者Hu Zhang

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 07:37:43