3

私のようにJSONレスポンスを返すREST APIを持っている:Jacksonの同じ名前で異なるタイプの属性を逆シリアル化しますか?

{ 
    "channel" : "JHBHS" 
} 

、時にはそれが返されます。

{ 
    "channel": { 
        "id": 12321, 
        "name": "Some channel" 
       } 
} 

私のようなPOJOていますので、そこ

public class Event { 
    private String channel; 
    @JsonProperty("channel") 
    private Channel channelObj; 
} 

public class Channel { 
    private int id; 
    private String name; 
} 

ですが(あなた自身のカスタムデシリアライザを書く以外に)Jackson2で私は地図に役立ちますchannelをJSONの場合Stringの場合はStringChannelの場合はJSONオブジェクトですか?

つまり、変数のtypeでマッピングする方法がありますか?name

class Event { 

    @JsonProperty("channel") 
    private JsonNode channelInternal; 

    private Channel channel; 

    private String channelStr; 

    /** 
    * Custom getter with channel parsing 
    * @return channel 
    */ 
    public Channel getChannel() { 
     if (channel == null && channelInternal != null) { 
      if (channelInternal.isObject()) { 
       int id = channelInternal.get("id").intValue(); 
       String name = channelInternal.get("name").asText(); 
       channel = new Channel(id, name); 
      } 
     } 
     return channel; 
    } 

    /** 
    * Custom getter with channel string parsing 
    * @return channel string 
    */ 
    public String getChannelStr() { 
     if (channelStr == null && channelInternal != null) { 
      if (channelInternal.isTextual()) { 
       channelStr = channelInternal.asText(); 
      } 
     } 
     return channelStr; 
    } 
} 

をか、このような

+0

私は別の同様の質問http://stackoverflow.com/questions/21790727/providing-jackson-mapper-multiple-を見つけました同じオブジェクトを反並列化する方法 –

答えて

5

私はあなたがこのようなJsonNodeを使用することをお勧めすることができます

class Event { 

    private Channel channel; 

    private String channelStr; 

    @JsonSetter("channel") 
    public void setChannelInternal(JsonNode channelInternal) { 
     if (channelInternal != null) { 
      if (channelInternal.isTextual()) { 
       channelStr = channelInternal.asText(); 
      } else if (channelInternal.isObject()) { 
       int id = channelInternal.get("id").intValue(); 
       String name = channelInternal.get("name").asText(); 
       channel = new Channel(id, name); 
      } 
     } 
    } 

    public Channel getChannel() { 
     return channel; 
    } 

    public String getChannelStr() { 
     return channelStr; 
    } 
} 

をしかし、私はカスタムデシリアライザを使用すると、より一般的だと思います。ここで

は、テストコードが

public static void main(String[] args) throws IOException { 
    ObjectMapper objectMapper = new ObjectMapper(); 
    String source1 = "{\n" + 
      " \"channel\" : \"JHBHS\"\n" + 
      "}"; 
    String source2 = "{\n" + 
      " \"channel\": {\n" + 
      "     \"id\": 12321,\n" + 
      "     \"name\": \"Some channel\"\n" + 
      "    }\n" + 
      "}"; 

    //Test object parsing 
    Event result = objectMapper.readValue(source2, Event.class); 
    System.out.println(String.format("%s : %s", result.getChannel().getId(), result.getChannel().getName())); 

    //Test string parsing 
    result = objectMapper.readValue(source1, Event.class); 
    System.out.println(result.getChannelStr()); 
} 

されて出力される。

12321 : Some channel 
JHBHS 
+0

非常に詳細な答えです。しかし、カスタムセッターメソッドは、このhttp://stackoverflow.com/a/27068928/1385441のようにここで仕事をしませんか? –

+0

@Ramswaroop、http://stackoverflow.com/questions/21790727/providing-jackson-mapper-multiple-ways-to-deserialize-the-same-object/27068928#27068928 – Vadeg

関連する問題