2013-11-28 54 views
3

轉換我創建了以下節儉對象:節儉 - 從簡單的JSON

struct Student{ 
     1: string id; 
     2: string firstName; 
     3: string lastName 
} 

現在我想讀取JSON此對象。根據這一post這是可能的

所以我寫了下面的代碼:

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) 

我缺少的東西?

+0

首先將您的JSON解析爲地圖和列表,然後轉儲並理解它。然後弄清楚如何提取你想要的數據。 –

+0

我很抱歉,但我沒有理解你的觀點。我應該解析什麼json。我有非常簡單的節儉結構,不需要地圖和列表。 –

+1

問題是你使用的工具比你需要的更復雜(並且理解)。開始簡單。 –

回答

5

您錯過了Thrift的JSON與您的不同之處。字段名稱不寫入,而是寫入(和預期)分配的字段ID號。下面是節儉的JSON協議的示例:

[1,"MyService",2,1,{"1":{"rec":{"1":{"str":"Error: Process() failed"}}}}] 

換句話說,節儉並不旨在解析任何種類JSON的。它支持非常特定的JSON格式作爲可能的傳輸方式之一。

但是,根據您的JSON數據的來源,Thrift可能仍然可以幫助您,如果您能夠在兩側使用它。在這種情況下,編寫IDL來描述數據結構,將其提供給Thrift編譯器,並將生成的代碼和庫的必要部分與項目集成。

如果JSON的來源不在您的範圍之內,或者由於某種原因無法更改JSON格式,則需要另外尋找方法。

格式和語義是不同的野獸

在一定程度上,整個問題可以用XML進行比較:有一個通用的XML語法,它告訴我們,我們怎麼也得fomat東西,所以任何標準符合性XML處理器可以讀取它們。

但是,知道XML的規則只有一半的答案,如果我們從某人得到某個XML文件。即使我們的XML解析器可以成功讀取文件,因爲它是格式良好的XML,我們需要知道數據的語義以真正利用該文件中的內容:它是否爲customer data record?或者它是一個SOAP envelope?也許是configuration file

這就是DTD或XML模式起作用的地方,它們存在來描述XML數據的內容。不知道您丟失的邏輯結構,因爲有無數種可能的方式來表達XML中的內容。對於JSON也是如此,除了JSON schema descriptions不太常用。

所以你的意思是,我們只需要一種方法來告訴節儉的JSON是如何組織的?

沒有,因爲其目的和背後的思想節儉是有一個框架,以解/連載事物和/或儘可能高效地實現RPC服務器和客戶端。它不打算有一個通用的文件分析器。相反,Thrift讀取和說明只有它自己的一套格式,它們是plugged into the architecture as protocols:Thrift Binary,Thrift JSON,Thrift Compact等等。

你可以做什麼:除了我在回答的第一部分所說的內容,你可以考慮編寫自己的自定義Thrift協議實現來支持你選擇的特定JSON格式。這並不難,值得一試。

+0

它看起來像Twitter序列化json使用相同的方法:https://github.com/twitter/commons/blob/master/src/java/com/twitter/common/io/ThriftCodec.java唯一的區別是,他們正在使用節儉0.5.0,我正在使用0.9.0。我會嘗試生成二進制文件並在此版本上運行我的代碼。我有一種感覺,自從0.5發佈以來,行爲已經發生了變化。 –

+0

@ danny.lesnik:你讀過評論嗎?它說「*可以編碼和解碼節儉結構的編解碼器*」 - 它不會說「*編解碼器可以編碼和解碼任何JSON結構*」。 – JensG