使用ObjectMapper对含有任意key的JSON进行反序列化

使用ObjectMapper对含有任意key的JSON进行反序列化

在调用某个RESTful API后,返回的JSON字符串中含有没有预先定义的key,和结构固定的JSON相比,它需要一些额外的操作。

对于结构固定的JSON,使用ObjectMapper结合某个预先定义的实体类型可以非常方便地完成反序列化工作,比如对下面这样的JSON:

GET /person/1

{
"id": "1",
"name": "dm_vincent",
"age": "28"
}


结合一个实体类型,可以很轻松的完成反序列化工作:

public class Person {
public long id;
public String name;
public int age;
}

public static <T> T getEntity(String jsonString, Class<T> prototype) {

ObjectMapper objectMapper = new ObjectMapper();
try {
return (T) objectMapper.readValue(jsonString, prototype);
} catch (IOException e) {
e.printStackTrace();
}

return null;
}


但是在某些支持一次性获取多条记录的API中,就出现问题了。比如拥有下面这种格式的API:

GET /person/1,2,3

{
"dm_vincent": {
"id": "1",
"name": "dm_vincent",
"age": "28"
},
"dm_vincent2": {
"id": "2",
"name": "dm_vincent2",
"age": "29"
},
"dm_vincent3": {
"id": "3",
"name": "dm_vincent3",
"age": "30"
}
}


虽然需要获取的实体类型还是那个Person类,可是这个时候就不像上面那样简单明了了。比如下面这段代码在反序列化的时候会出现问题:

public class PersonWrapper {
public Map<String, Person> persons;
}


我们的意图是明确的,将返回的多个Person实体对象放到一个Map结构中。但是问题就在于返回的JSON中的keys是不固定的(比如上述JSON中的keys是人名),这导致反序列化失败。毕竟默认配置下的ObjectMapper也没有聪明到这种程度,能够猜测你是想要将多个实体放到Map中。

正确的做法之一是使用ObjectMapper的readTree方法:

public static <T> EntityWrapper<T> getEntityWrapper(String jsonString, Class<T> prototype) {
ObjectMapper objectMapper = new ObjectMapper();
EntityWrapper<T> wrapper = new EntityWrapper<T>();
try {
JsonNode root = objectMapper.readTree(jsonString);
Iterator<Entry<String, JsonNode>> elements = root.fields();

while (elements.hasNext()) {
Entry<String, JsonNode> node = elements.next();
String key = node.getKey();
T element = objectMapper.readValue(node.getValue().toString(), prototype);
wrapper.addEntry(key, element);
}

return wrapper;
} catch (IOException e) {
e.printStackTrace();
}

return null;
}


简单解释一下上述代码:

使用root.field()方法能够得到返回的JSON中的所有key-value对。
然后循环提取某个键值对的key和value,对于value我们可以直接使用之前的策略进行反序列化,因为这部分的结构也是固定的。

[size=medium][color=blue][b]忽略不需要的字段[/b][/color][/size]

有时候,返回的JSON字符串中含有我们并不需要的字段,那么当对应的实体类中不含有该字段时,会抛出一个异常,告诉你有些字段没有在实体类中找到。解决办法很简单,在声明ObjectMapper之后,加上上述代码:

ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);


//让Json可以缩进,可读性更好,一般用在测试和开发阶段。
mapper.configure(SerializationFeature.INDENT_OUTPUT, true);
//让map的key按自然顺序排列
mapper.configure(SerializationFeature.ORDER_MAP_ENTRIES_BY_KEYS, true);
//日期输出格式
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd");
mapper.setDateFormat(outputFormat);

转自:http://blog.csdn.net/dm_vincent/article/details/46764399

http://jackyrong.iteye.com/blog/2005323
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
LinkList是Java中的链表数据结构,它的特点是每个节点中都包含指向下一个节点的引用。Hash Map是Java中的散列表数据结构,它通过将键映射到值的方式来存储和访问元素。ObjectMapper是Jackson库中的一个类,用于将JSON数据反序列化为Java对象。 当需要将JSON数据反序列化为LinkList或Hash Map对象时,可以使用ObjectMapper类的readValue方法。该方法接受两个参数,第一个参数是要反序列化JSON数据,第二个参数是要生成的目标对象类型。例如,以下是将JSON数据反序列化为LinkList对象的示例代码: ``` String json = "[1, 2, 3]"; ObjectMapper objectMapper = new ObjectMapper(); LinkList<Integer> list = objectMapper.readValue(json, new TypeReference<LinkList<Integer>>(){}); ``` 在上面的代码中,json变量表示要反序列化JSON数据。然后,我们创建了一个ObjectMapper对象,并使用其readValue方法来将json反序列化为LinkList<Integer>对象。由于泛型在运行时会被擦除,因此我们需要使用TypeReference类来指定反序列化的目标类型。 同样地,我们也可以将JSON数据反序列化为Hash Map对象。以下是示例代码: ``` String json = "{\"key1\":\"value1\", \"key2\":\"value2\"}"; ObjectMapper objectMapper = new ObjectMapper(); Hash Map<String, String> map = objectMapper.readValue(json, new TypeReference<Hash Map<String, String>>(){}); ``` 在上面的代码中,json变量表示要反序列化JSON数据。然后,我们创建了一个ObjectMapper对象,并使用其readValue方法将json反序列化为Hash Map<String, String>对象。 总结来说,通过使用ObjectMapper类的readValue方法,我们可以将JSON数据反序列化为LinkList或Hash Map对象,从而方便地进行后续的操作和处理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值