2016-06-21 8 views
7

これは、かなり解決された/よく取り組まれた問題であるようですが、私は多くのガイダンスを見つけられません。JSONレスポンス内のネストされたオブジェクトからのフィールドの逆シリアル化

私のシナリオでは、私はこのような何かを見て、ページ付けJSONレスポンスを消費していますことを、基本的である:

{ 
    "objects": [...], 
    "meta": { 
    "total": 5000, 
    "page": 1, 
    "result_pages": 20, 
    "links": { 
     "prev": null, 
     "next": "/api/v3/objects/somequery?page=2" 
    } 
    } 
} 

明らかにこれは単純化され、うまくいけば、それは全体でポイントを取得します。

本当に気になるのは、objectsフィールドとnextフィールドですが、ネストされたフィールドを正常にデシリアライズするには、DTOの階層全体を作成する必要があります。

このすべてをスキップできるジャクソンアノテーションはありますか?そうでない場合は、主に空のクラスやファイルが含まれていない、これを行うベストプラクティスがありますか?

答えて

8

これをすべてスキップできるジャクソンアノテーションがありますか?

を使用して、カスタムJsonDeserializerを定義できます。

class MetaDeserializer extends JsonDeserializer<String> { 
    @Override 
    public String deserialize(JsonParser jp, DeserializationContext ctx) throws IOException { 
     JsonNode tree = jp.readValueAsTree(); 
     return tree.get("links").get("next").asText(); 
    } 
} 

ここでは単純なマップの逆シリアル化を使用しましたが、必要に応じて独自の高速逆シリアル化を実装できます。

とオブジェクト

class MetaObject { 
    public List<Integer> objects; 

    @JsonDeserialize(using = MetaDeserializer.class) 
    public String meta; 

    @Override 
    public String toString() { 
     return "MetaObject{" + "objects=" + objects + ", meta='" + meta + '\'' + '}'; 
    } 
} 

そして、あなたはMetaObject result = mapper.readValue("...", MetaObject.class)を起動する場合は、あなたが

MetaObject{objects=[1, 2, 3], meta='/api/v3/objects/somequery?page=2'} 
+1

が、多分ちょうど上の注釈で、上記の 'JsonDeserializer'を使用することが容易になるだろう欲しいものを得るでしょう'String next'プロパティを使用して、' 'オブジェクト ''と同じルートレベルで、それがフラットであるとふりまとめますか? –

+0

@ap、この注釈は、クラストップの場合でも、別の方法で使用することができます。ここでは、ドキュメントhttps://fasterxml.github.io/jackson-databind/javadoc/2.3.0/com/fasterxml/jackson/databind /annotation/JsonDeserialize.html – SerCe

+1

将来の疑問がある場合は、上記の答えが間違っていると思われる '.asText()'メソッドを使用していることを言及する必要があります。私は '.textValue()'を使い終わってしまいました。それは魅力的に働いています。 –

関連する問題