Java 节约-从简单JSON转换

Java 节约-从简单JSON转换,java,json,thrift,thrift-protocol,Java,Json,Thrift,Thrift Protocol,我创建了以下节约对象: struct Student{ 1: string id; 2: string firstName; 3: string lastName } 现在我想从JSON中读取这个对象。根据这一点,这是可能的 因此,我编写了以下代码: String json = "{\"id\":\"aaa\",\"firstName\":\"Danny\",\"lastName\":\"Lesnik\"}"; StudentThrift

我创建了以下节约对象:

struct Student{
        1: string id;
        2: string firstName;
        3: string lastName
}
现在我想从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);
我得到的是以下例外情况:

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)

我遗漏了什么吗?

您遗漏了一个事实,即Thrift的JSON与您的JSON不同。不会写入字段名称,而是写入(且预期)指定的字段ID号。下面是Thrift的JSON协议示例:

[1,"MyService",2,1,{"1":{"rec":{"1":{"str":"Error: Process() failed"}}}}]
换句话说,Thrift并不打算解析任何类型的JSON。它支持一种非常特定的JSON格式作为可能的传输方式之一

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

如果JSON的来源超出了您的能力范围,或者由于某种原因无法更改JSON格式,那么您需要找到另一种方法

格式和语义不同

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

但是,如果我们从某人那里得到某个XML文件,了解XML的规则仅仅是答案的一半。即使我们的XML解析器能够成功地读取文件,因为它是格式良好的XML,我们也需要知道数据的语义,以便真正利用该文件中的内容:它是一个XML文件吗?或者它是一个?也许一个

这就是DTD或XML模式发挥作用的地方,它们的存在是为了描述XML数据的内容。在不知道逻辑结构的情况下,您会迷失方向,因为有无数种可能的方式可以用XML来表达。JSON也是如此,只是不太常用

“那么你的意思是,我们需要一种方法来告诉Thrift JSON是如何组织的?”

不,因为Thrift背后的目的和思想是要有一个框架来尽可能高效地对事物进行反序列化和/或实现RPC服务器和客户端。它不打算有一个通用文件解析器。相反,Thrift只读取和说出自己的一组格式,即:Thrift二进制、Thrift JSON、Thrift Compact等


<强>您能做什么:<强> >除了我在回答的第一节中所说的,您可以考虑编写自己的自定义节俭协议实现,以支持您选择的特定JSON格式。这并不难,值得一试

首先将JSON解析为映射和列表,然后转储并理解它。然后想办法提取你想要的数据。很抱歉,我没有回答你的问题。我应该解析什么json。我有一个非常简单的储蓄结构,不需要地图和列表。问题是你使用的工具比你需要的(和理解的)复杂。一开始很简单。看起来twitter正在使用相同的方法序列化json:唯一的区别是他们使用的是thrift 0.5.0,而我使用的是0.9.0。我将尝试生成二进制文件并在此版本上运行代码。我感觉自0.5版发布以来,人们的行为发生了变化。@danny.lesnik:你读过上面的评论了吗?它说“一个可以编码和解码节俭结构的编解码器”——它没有说“一个可以编码和解码任何JSON结构的编解码器”。