使用 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) 。为了克服这个限制,杰克逊提供了两种方法 - TypeFactory
和 TypeReference
。
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
方法可能看起来更好,但它有几个缺点:
TypeReference
应该使用匿名类进行实例化- 你应该提供通用的明确性
如果不这样做可能会导致泛型类型参数的丢失,从而导致反序列化失败。