2016-02-04 16 views
5

私はそれが配列であるフィールドを持つエンティティを提供するサービスを消費しようとしています。ジャクソンは単一のアイテムをリストにデシリアライズする

{ 
    "id": "23233", 
    "items": [ 
    { 
     "name": "item 1" 
    }, 
    { 
     "name": "item 2" 
    } 
    ] 
} 

しかし、アレイは単一の項目が含まれている場合、項目自体ではなく一つの要素のアレイ、返されます。

{ 
    "id": "43567", 
    "items": { 
     "name": "item only" 
    } 
} 

この場合、Jacksonは自分のJavaオブジェクトに変換できません。

public class ResponseItem { 

    private String id; 
    private List<Item> items; 

    //Getters and setters... 
} 

直接的な解決策はありますか?

+0

これは、そのサービスにとってかなり奇妙な動作のようです。プロバイダーにそれを修正するよう指示する機会はありますか? – Thomas

+0

@トーマス残念ながら。これは数百人のユーザーを抱える大きなSaaSプロバイダーであり、私はそのうちのひとつです。 – WinterN

答えて

8

あなたはこの問題を最初に尋ねることはありません。それはかなり古いようです。ドキュメントを

ルック: http://fasterxml.github.io/jackson-databind/javadoc/2.5/com/fasterxml/jackson/databind/DeserializationFeature.html#ACCEPT_SINGLE_VALUE_AS_ARRAY

あなたのオブジェクトマッパーにこのジャクソンの機能を追加する必要が

この問題を見た後、あなたはDeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAYを使用することができます。

私はそれがあなたを助けてくれることを願っています。

-2

私はかなりGsonがこじんまりした状態でこれを行うことができます。もしあなたがそれにこだわっているなら、誰かがジャクソンを助けてくれることを願っています。

(例:https://stackoverflow.com/a/18547661/1638595

EDIT:代わりに "できない" の "うまくいけば、誰かが...あなたを助けることができる":へぇ、申し訳ありませんと言うことを意味しました。登場したのは失礼だ。

1

カスタムJsonDeserializerを使用してこれを解決できます。

など。それが動作することを後

@JsonDeserialize(using = CustomDeserializer.class) 
private List<Item> items; 

class CustomDeserializer extends JsonDeserializer<List<Item>> { 

    @Override 
    public List<Item> deserialize(JsonParser jsonParser, DeserializationContext context) 
      throws IOException, JsonProcessingException { 

     JsonNode node = jsonParser.readValueAsTree(); 

     List<Item> items = new ArrayList<>(); 
     ObjectMapper mapper = new ObjectMapper(); 

     if (node.size() == 1) { 
      Item item = mapper.readValue(node.toString(), Item.class); 
      items.add(item); 

     } else { 
      for (int i = 0; i < node.size(); i++) { 
       Item item = mapper.readValue(node.get(i).toString(), Item.class); 
       items.add(item); 
      } 
     } 

     return items; 
    } 

} 

あなたは次のように、itemsをデシリアライズするためにこれを使用するためにジャクソンを指示する必要があります。ハッピーコーディング:)

+0

これは悪いです。複数のレベルの配列として単一の値を必要とする深い構造では機能しません。別のマッパーを使用して、List ブランチ全体をデシリアライズする。追加のマッパーはすべてのリストの逆シリアル化でインスタンス化されます。 –

関連する問題