7

次の Thrift オブジェクトを作成しました。

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)

何か不足していますか?

4

1 に答える 1

7

Thrift の JSON があなたのものとは異なるという事実を見逃しています。フィールド名は書き込まれず、代わりに割り当てられたフィールド ID 番号が書き込まれます (期待されます)。Thrift の JSON プロトコルの例を次に示します。

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

つまり、Thrift は、いかなる種類の JSON も解析することを意図していません。可能なトランスポートの 1 つとして、非常に特殊な JSON 形式をサポートします。

ただし、JSON データの出所によっては、Thrift を両側で使用できる場合は、まだ役立つ可能性があります。その場合、IDL を記述してデータ構造を記述し、それを Thrift コンパイラにフィードして、生成されたコードとライブラリの必要な部分の両方をプロジェクトに統合します。

JSON の元が手の届かないところにある場合、または何らかの理由で JSON 形式を変更できない場合は、別の方法を見つける必要があります。

フォーマットとセマンティクスは別物

ある程度、問題全体を XML と比較することができます。一般的な XML 構文が 1 つあります。これは、標準に準拠した XML プロセッサが読み取れるように、どのように書式設定する必要があるかを示しています。

しかし、誰かから特定の XML ファイルを入手した場合、XML の規則を知っているだけでは答えの半分にすぎません。XML パーサーがファイルを正常に読み取ることができたとしても、それは整形式の XML であるため、そのファイル内の内容を実際に利用するには、データのセマンティクスを知る必要があります。それは顧客データ レコードですか? それともSOAPエンベロープですか?多分設定ファイル

そこで DTD または XML スキーマの出番です。それらは XML データの内容を記述するために存在します。XML で物事を表現する方法は無数にあるため、論理構造を知らなければ、道に迷ってしまいます。また、 JSON スキーマ記述があまり一般的に使用されていないことを除けば、JSON についてもまったく同じことが当てはまります。

ということは、JSON がどのように構成されているかを Thrift に伝える方法だけが必要ということですか?

いいえ、Thrift の背後にある目的とアイデアは、可能な限り効率的に物事をデシリアライズしたり、RPC サーバーとクライアントを実装したりするためのフレームワークを用意することです。汎用ファイル パーサーを使用することは意図されていません。代わりに、Thrift は、プロトコルとしてアーキテクチャにプラグインされている独自の形式のセットのみを読み込んで話します: Thrift Binary、Thrift JSON、Thrift Compact など。

できること:回答の最初のセクションで述べたことに加えて、選択した特定の JSON 形式をサポートする独自のカスタム Thrift プロトコル実装を作成することを検討してください。それほど難しいことではなく、試してみる価値があります。

于 2013-11-28T18:36:04.377 に答える