使用 Jackson 将 JSON 集合反序列化为对象集合

假设你有一个 pojo 类 Person

public class Person {
    public String name;

    public Person(String name) {
        this.name = name;
    }
}

并且你希望将其解析为 JSON 数组或 Person 对象的映射。由于类型擦除,你无法在运行时直接构造 List<Person>Map<String, Person> 的类 (因此使用它们来反序列化 JSON) 。为了克服这个限制,杰克逊提供了两种方法 - TypeFactoryTypeReference

TypeFactory

这里采用的方法是使用工厂(及其静态实用程序功能)为你构建类型。它所使用的参数是你要使用的集合(列表,集等)以及要存储在该集合中的类。

TypeReference

类型参考方法似乎更简单,因为它可以节省你一些打字和看起来更干净。TypeReference 接受一个类型参数,你可以在其中传递所需的类型 List<Person>。你只需实例化此 TypeReference 对象并将其用作类型容器。

现在让我们看看如何将 JSON 实际反序列化为 Java 对象。如果你的 JSON 格式化为数组,则可以将其反序列化为 List。如果存在更复杂的嵌套结构,则需要反序列化为 Map。我们将看看两者的例子。

反序列化 JSON 数组

String jsonString = "[{\"name\": \"Alice\"}, {\"name\": \"Bob\"}]"

TypeFactory 方法

CollectionType listType = 
    factory.constructCollectionType(List.class, Person.class);
List<Preson> list = mapper.readValue(jsonString, listType);

TypeReference 方法

TypeReference<Person> listType = new TypeReference<List<Person>>() {};
List<Person> list = mapper.readValue(jsonString, listType);

反序列化 JSON 映射

String jsonString = "{\"0\": {\"name\": \"Alice\"}, \"1\": {\"name\": \"Bob\"}}"

TypeFactory 方法

CollectionType mapType = 
    factory.constructMapLikeType(Map.class, String.class, Person.class);
List<Person> list = mapper.readValue(jsonString, mapType);

TypeReference 方法

TypeReference<Person> mapType = new TypeReference<Map<String, Person>>() {};
Map<String, Person> list = mapper.readValue(jsonString, mapType);

细节

使用的导入语句:

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.type.CollectionType;

使用的实例:

ObjectMapper mapper = new ObjectMapper();
TypeFactory factory = mapper.getTypeFactory();

注意

虽然 TypeReference 方法可能看起来更好,但它有几个缺点:

  1. TypeReference 应该使用匿名类进行实例化
  2. 你应该提供通用的明确性

如果不这样做可能会导致泛型类型参数的丢失,从而导致反序列化失败。