Jackson全局设置将数组反序列化为自定义列表实现 [英] Jackson global settings to deserialise array to custom list implementation
问题描述
默认情况下,Jackson使用java.util.ArrayList
反序列化JSON数组.取而代之的是,我想使用自定义实现.例如,如果存在值,则使用Guava ImmutableList
;如果JSON数组为空或null,则使用Collection.emptyList()
.
By default, Jackson is using java.util.ArrayList
to deserialise a JSON array. Instead of this, I want to use a custom implementation. For example, Guava ImmutableList
if value is present, or Collection.emptyList()
if JSON array is empty or null.
我想为ObjectMapper
全局配置它.有没有简单的方法可以做到这一点?
I want to configure this globally for ObjectMapper
. Is there an easy way to do this?
PS:我的杰克逊版本为2.9.7
PS: My Jackson version is 2.9.7
推荐答案
常规解决方案是使用自定义模块.您可以定义要用于集合的类.对于番石榴,有一个Maven模块:
General solution is to use custom module. You can define classes you would like to use for collections. For Guava there is a Maven module:
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-guava</artifactId>
<version>x.y.z</version>
</dependency>
现在,您可以注册新模块了:
Now, you can register your new module:
ObjectMapper mapper = new ObjectMapper();
// register module with object mapper
mapper.registerModule(new GuavaModule());
现在,您可以在POJO
中定义要对列表进行不可变的实现.
Now, you can define in your POJO
you want to have immutable implementation of the list.
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
类与List
实现联系在一起,则需要使用SimpleModule
类添加一些额外的配置.因此,您的POJO
如下所示:
If you do not want to tie your POJO
classes with List
implementation you need to add some extra configuration using SimpleModule
class. So, your POJO
looks like below:
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
时:
When you remove extra SimpleModule
above code prints:
Pojo{ints=[1, 2, 3, 4] class java.util.ArrayList}
在Collections.emptyList()
为空的情况下,我看不出有什么要使用的地方. Guava
的模块将RegularImmutableList
用于非空数组和空数组.
I do not see any point to use Collections.emptyList()
in case it is empty. Guava
's module uses RegularImmutableList
for not empty and empty arrays.
要转换null -> empty
,请参见以下问题:
For converting null -> empty
see this question:
,但我建议将其设置为POJO
中的empty
,如下所示:
but I recommend to set it to empty
in POJO
like below:
private List<Integer> ints = Collections.emptyList();
这篇关于Jackson全局设置将数组反序列化为自定义列表实现的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!