反序列化杰克逊中同名但不同类型的属性?
Posted
技术标签:
【中文标题】反序列化杰克逊中同名但不同类型的属性?【英文标题】:Deserializing attributes of same name but different types in Jackson? 【发布时间】:2016-10-15 05:49:30 【问题描述】:我有一个 REST API,它返回一个 JSON 响应:
"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 中可以帮助我将JSON 中的channel
映射到String
类型,当它是String
时和Channel
类型当它是一个JSON 对象?
或者换句话说,Jackson 有没有办法通过变量的type
而不仅仅是name
进行映射?
【问题讨论】:
我发现了另一个类似的问题***.com/questions/21790727/… 【参考方案1】:我可以建议你像这样使用JsonNode:
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;
或像这样:
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
【讨论】:
非常详细的答案。但是自定义 setter 方法不会像 ***.com/a/27068928/1385441 那样在这里完成工作吗? @Ramswaroop,刚刚用***.com/questions/21790727/…中描述的第二个变体更新了答案以上是关于反序列化杰克逊中同名但不同类型的属性?的主要内容,如果未能解决你的问题,请参考以下文章