[Jackson] 使用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我们可以直接使用之前的策略进行反序列化,因为这部分的结构也是固定的。


忽略不需要的字段

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

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-26 12:59:30

[Jackson] 使用ObjectMapper对含有任意key的JSON进行反序列化的相关文章

com.fasterxml.jackson.databind.ObjectMapper操作对象和集合的一些相互转换用法

概述 JacksonTest AccountBean Birthday 概述 原文链接:http://blog.csdn.net/u011506468/article/details/47342667 最近用到了ObjectMapper,做了些实验.主要有以下一些转换方式: JavaBean(Entity/Model)转换成JSON 将Map集合转换成Json字符串 将List集合转换成json 将json字符串转换成JavaBean对象 将json字符串转换成List集合 将json字符串转换

将任意格式转换为JSON数据格式的工具类

Java的将任意格式转换为JSON数据格式的工具类 package org.sjw.utils; import java.beans.IntrospectionException; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.util.List; import java.util.Map; import java.util.Set; public class JsonUtils

比较任意两个JSON串是否相等(比较对象是否相等)JAVA版

废话少说,直接入题. 在面向对象语言中,经常会比较两个对象是否相等,而比较的大多是实体类实例,也就是封装数据的那些类实例,或者是Map.List互相嵌套成的复杂数据结构. 比较对象是否相等,常见的思路是重写equals方法,但鉴于对象的种类多变,嵌套层次复杂,仅仅靠重写equals是很难实现的. 小菜的思路是可以把对象序列化,由于这些对象均是用来表达数据结构,因此可以直接转换成JSON字符串,用字符串来描述数据结构,避免实现Serializable接口.将对象序列化成字符串后,比较是否相等就相对

利用ObjectMapper readValue()和泛型解决复杂json结构

1 import com.dj.fss.vo.MessageListVO; 2 import com.fasterxml.jackson.annotation.JsonIgnoreProperties; 3 import com.fasterxml.jackson.core.JsonParseException; 4 import com.fasterxml.jackson.databind.JsonMappingException; 5 import com.fasterxml.jackson

解析没有key的Json

没有key的Json,例如:["http://www.cnblogs.com/Cherry-B/p/4625133.html","http://www.cnblogs.com/Cherry-B/p/4619689.html","http://www.cnblogs.com/Cherry-B/p/4613701.html"] public void alyJson(String urls) { ArrayList<String> url

python:解析js中常见的 不带引号的key的 json

首先要明晰一点,json标准中,key是必须要带引号的,所以标准json模块解析不带引号的key的 json就会抛错 不过有一些lib可以帮我们解析 如:demjson(链接) >>>> import demjson >>> demjson.decode('{suggestion:[{query:"London",interpretation: ...') {u'suggestion': [{u'query': u'London', u'ope

spray json, jackson 转到type时多key和少key的比较

有组合关系的三个class定义 A { B { C {...} ... } ... } 每个class都有loadFromJson和writeAsJson方法.过去几年,三个class里的成员变量一直在添加,而数据库里有很多json string类型的老数据,为了能够正确的把它们转化为class,就需要对一些域进行判断,举个例子. 在 db 中有一个json string,是这样的 name: xins, age: 24 而几年后C添加了一个新的域,company 那么loadFromJson就

com.fasterxml.jackson.databind.ObjectMapper. .readValue .convertValue

String str="{\"student\":[{\"name\":\"leilei\",\"age\":23},{\"name\":\"leilei02\",\"age\":23}]}"; Student stu = null; List<Student> list = null; try { ObjectMapper objec

含有任意量词与存在量词的最值问题

原文地址:https://www.cnblogs.com/xuebajunlutiji/p/9317062.html