将数组反序列化为自定义列表实现的 Jackson 全局设置
Jackson global settings to deserialise array to custom list implementation
默认情况下,Jackson 使用 java.util.ArrayList
反序列化 JSON 数组。而不是这个,我想使用自定义实现。例如,Guava ImmutableList
如果值存在,或 Collection.emptyList()
如果 JSON 数组为空或 null。
我想为 ObjectMapper
进行全局配置。有没有简单的方法可以做到这一点?
PS: 我的 Jackson 版本是 2.9.7
我认为不存在简单的方法,因为 CollectionDeserializer
在解析之前创建集合实例。因此,为此目的,您需要创建自定义解串器。
但我不确定=))
一般的解决方案是使用自定义模块。您可以定义要用于集合的 classes。对于番石榴,有一个 Maven 模块:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-guava</artifactId>
<version>x.y.z</version>
</dependency>
现在,您可以注册您的新模块:
ObjectMapper mapper = new ObjectMapper();
// register module with object mapper
mapper.registerModule(new GuavaModule());
现在,您可以在 POJO
中定义您想要列表的不可变实现。
class Pojo {
private ImmutableList<Integer> ints;
public ImmutableList<Integer> getInts() {
return ints;
}
public void setInts(ImmutableList<Integer> ints) {
this.ints = ints;
}
@Override
public String toString() {
return "Pojo{" +
"ints=" + ints + " " + ints.getClass() + '}';
}
}
及以下示例:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new GuavaModule());
String json = "{\"ints\":[1,2,3,4]}";
System.out.println(mapper.readValue(json, Pojo.class));
打印:
Pojo{ints=[1, 2, 3, 4] class com.google.common.collect.RegularImmutableList}
如果您不想将 POJO
class 与 List
实现联系起来,您需要使用 SimpleModule
class 添加一些额外的配置。因此,您的 POJO
如下所示:
class Pojo {
private List<Integer> ints;
public List<Integer> getInts() {
return ints;
}
public void setInts(List<Integer> ints) {
this.ints = ints;
}
@Override
public String toString() {
return "Pojo{" +
"ints=" + ints + " " + ints.getClass() + '}';
}
}
您的示例如下所示:
SimpleModule useImmutableList = new SimpleModule("UseImmutableList");
useImmutableList.addAbstractTypeMapping(List.class, ImmutableList.class);
GuavaModule module = new GuavaModule();
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
mapper.registerModule(useImmutableList);
String json = "{\"ints\":[1,2,3,4]}";
System.out.println(mapper.readValue(json, Pojo.class));
以上代码打印:
Pojo{ints=[1, 2, 3, 4] class com.google.common.collect.RegularImmutableList}
当你删除额外的 SimpleModule
上面的代码打印:
Pojo{ints=[1, 2, 3, 4] class java.util.ArrayList}
如果它是空的,我认为使用 Collections.emptyList()
没有任何意义。 Guava
的模块使用 RegularImmutableList
表示非空和空数组。
要转换 null -> empty
请看这个问题:
但我建议在 POJO
中将其设置为 empty
,如下所示:
private List<Integer> ints = Collections.emptyList();
默认情况下,Jackson 使用 java.util.ArrayList
反序列化 JSON 数组。而不是这个,我想使用自定义实现。例如,Guava ImmutableList
如果值存在,或 Collection.emptyList()
如果 JSON 数组为空或 null。
我想为 ObjectMapper
进行全局配置。有没有简单的方法可以做到这一点?
PS: 我的 Jackson 版本是 2.9.7
我认为不存在简单的方法,因为 CollectionDeserializer
在解析之前创建集合实例。因此,为此目的,您需要创建自定义解串器。
但我不确定=))
一般的解决方案是使用自定义模块。您可以定义要用于集合的 classes。对于番石榴,有一个 Maven 模块:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-guava</artifactId>
<version>x.y.z</version>
</dependency>
现在,您可以注册您的新模块:
ObjectMapper mapper = new ObjectMapper();
// register module with object mapper
mapper.registerModule(new GuavaModule());
现在,您可以在 POJO
中定义您想要列表的不可变实现。
class Pojo {
private ImmutableList<Integer> ints;
public ImmutableList<Integer> getInts() {
return ints;
}
public void setInts(ImmutableList<Integer> ints) {
this.ints = ints;
}
@Override
public String toString() {
return "Pojo{" +
"ints=" + ints + " " + ints.getClass() + '}';
}
}
及以下示例:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new GuavaModule());
String json = "{\"ints\":[1,2,3,4]}";
System.out.println(mapper.readValue(json, Pojo.class));
打印:
Pojo{ints=[1, 2, 3, 4] class com.google.common.collect.RegularImmutableList}
如果您不想将 POJO
class 与 List
实现联系起来,您需要使用 SimpleModule
class 添加一些额外的配置。因此,您的 POJO
如下所示:
class Pojo {
private List<Integer> ints;
public List<Integer> getInts() {
return ints;
}
public void setInts(List<Integer> ints) {
this.ints = ints;
}
@Override
public String toString() {
return "Pojo{" +
"ints=" + ints + " " + ints.getClass() + '}';
}
}
您的示例如下所示:
SimpleModule useImmutableList = new SimpleModule("UseImmutableList");
useImmutableList.addAbstractTypeMapping(List.class, ImmutableList.class);
GuavaModule module = new GuavaModule();
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
mapper.registerModule(useImmutableList);
String json = "{\"ints\":[1,2,3,4]}";
System.out.println(mapper.readValue(json, Pojo.class));
以上代码打印:
Pojo{ints=[1, 2, 3, 4] class com.google.common.collect.RegularImmutableList}
当你删除额外的 SimpleModule
上面的代码打印:
Pojo{ints=[1, 2, 3, 4] class java.util.ArrayList}
如果它是空的,我认为使用 Collections.emptyList()
没有任何意义。 Guava
的模块使用 RegularImmutableList
表示非空和空数组。
要转换 null -> empty
请看这个问题:
但我建议在 POJO
中将其设置为 empty
,如下所示:
private List<Integer> ints = Collections.emptyList();