节俭 - 从简单的JSON转换

dan*_*nik 5 java json thrift thrift-protocol

我创建了以下Thrift对象:

struct Student{
        1: string id;
        2: string firstName;
        3: string lastName
}
Run Code Online (Sandbox Code Playgroud)

现在我想从JSON中读取这个对象.根据这篇文章,这是可能的

所以我写了下面的代码:

String json = "{\"id\":\"aaa\",\"firstName\":\"Danny\",\"lastName\":\"Lesnik\"}";
    StudentThriftObject s = new StudentThriftObject();
    byte[] jsonAsByte = json.getBytes("UTF-8");
    TMemoryBuffer memBuffer = new TMemoryBuffer(jsonAsByte.length);
    memBuffer.write(jsonAsByte);

    TProtocol proto = new TJSONProtocol(memBuffer);
    s.read(proto);
Run Code Online (Sandbox Code Playgroud)

我得到的是以下异常:

Exception in thread "main" org.apache.thrift.protocol.TProtocolException: Unexpected character:i
    at org.apache.thrift.protocol.TJSONProtocol.readJSONSyntaxChar(TJSONProtocol.java:322)
    at org.apache.thrift.protocol.TJSONProtocol.readJSONInteger(TJSONProtocol.java:698)
    at org.apache.thrift.protocol.TJSONProtocol.readFieldBegin(TJSONProtocol.java:837)
    at com.vanilla.thrift.example.entities.StudentThriftObject$StudentThriftObjectStandardScheme.read(StudentThriftObject.java:486)
    at com.vanilla.thrift.example.entities.StudentThriftObject$StudentThriftObjectStandardScheme.read(StudentThriftObject.java:479)
    at com.vanilla.thrift.example.entities.StudentThriftObject.read(StudentThriftObject.java:413)
    at com.vanilla.thrift.controller.Main.main(Main.java:24)
Run Code Online (Sandbox Code Playgroud)

我错过了什么吗?

Jen*_*nsG 6

你错过了Thrift的JSON与你的不同的事实.不写入字段名称,而是写入(和预期)指定的字段ID号.这是Thrift的JSON协议的一个例子:

[1,"MyService",2,1,{"1":{"rec":{"1":{"str":"Error: Process() failed"}}}}]
Run Code Online (Sandbox Code Playgroud)

换句话说,Thrift并不打算解析任何类型的JSON.它支持非常特定的JSON格式作为可能的传输之一.

但是,根据您的JSON数据的来源,Thrift可能仍然可以帮助您,如果您能够在双方使用它.在这种情况下,编写一个IDL来描述数据结构,将其提供给Thrift编译器,并将生成的代码和库的必要部分与您的项目集成.

如果JSON的原点位于您无法触及的范围之外,或者由于某种原因无法更改JSON格式,则需要找到另一种方法.

格式和语义是不同的野兽

在某种程度上,整个问题可以与XML进行比较:有一种通用的XML语法,它告诉我们如何填充事物,因此任何符合标准的XML处理器都可以读取它们.

但是,如果我们从某人那里获得某个XML文件,那么了解XML规则只是答案的一半.即使我们的XML解析器可以成功读取文件,因为它是格式良好的XML,我们需要知道数据的语义才能真正利用该文件中的内容:它是客户数据记录吗?或者它是一个SOAP信封?也许是配置文件

这就是DTD或XML Schema发挥作用的地方,它们用于描述XML数据的内容.在不知道您丢失的逻辑结构的情况下,因为有无数种可能的方式来表达XML中的内容.JSON完全相同,只是JSON模式描述不太常用.

" 所以你的意思是,我们只需要告诉Thrift如何组织JSON? "

不,因为Thrift背后的目的和想法是拥有一个框架来尽可能高效地去/序列化事物和/或实现RPC服务器和客户端.它不打算具有通用文件解析器.相反,Thrift只读取和说出它自己的一组格式,这些格式作为协议插入到体系结构中:Thrift Binary,Thrift JSON,Thrift Compact等等.

您可以做什么:除了我在答案的第一部分中所说的,您可以考虑编写自己的自定义Thrift协议实现来支持您选择的特定JSON格式.这并不难,值得一试.