[英]Custom Jackson Deserializer to omit mapping of certain objects
I have a large JSON file that is made up of structures that I am mapping into POJOs, and then storing in a Collection. 我有一个很大的JSON文件,该文件由我映射到POJO并存储在Collection中的结构组成。 The structure is similar to this:
结构类似于此:
[
{
"id": 1234,
"file": "C:\\Programs\\Program1.exe",
"exists": true
}
{
"id": 5678,
"file": "C:\\Programs\\Program2.exe",
"exists": false
}
...
]
Using the Jackson streaming API I have got all these structures read, and the POJOs stored in a Collection successfully. 使用Jackson的流式API,我已经读取了所有这些结构,并且POJO成功存储在Collection中。 My POJO class looks like this:
我的POJO类如下所示:
public class Programs
{
@JsonProperty("id")
private Integer id;
@JsonProperty("file")
private String file;
@JsonProperty("exists")
private Boolean exists;
@JsonGetter("id")
public Integer getId()
{
return id;
}
@JsonGetter("file")
public String getFile()
{
return file;
}
@JsonGetter("exists")
public Boolean getExists()
{
return exists;
}
}
However, I want to omit any structures that have "exists"
set to false
during the deserialization process so that no POJO is ever created for them. 但是,我想在反序列化过程中忽略
"exists"
设置为false
任何结构,这样就不会为它们创建POJO。 So I wrote a custom deserializer with the help of this SO question [ How do I call the default deserializer from a custom deserializer in Jackson ], with my overridden deserialize
looking like: 因此,我借助此SO问题[ 如何从Jackson的自定义解串器中调用默认的解串器 ]编写了一个自定义解串器,而覆盖的
deserialize
如下所示:
@Override
public Programs deserialize(JsonParser parser, DeserializationContext context)
throws IOException
{
Programs programs = (Programs)defaultDeserializer.deserialize(parser, context);
if (!programs.getExists())
{
throw context.mappingException("[exists] value is false.");
}
return programs;
}
However, when I run some unit tests, I get the following error: 但是,当我运行一些单元测试时,出现以下错误:
"Can not deserialize instance of java.util.ArrayList out of START_OBJECT token"
message was "Class com.myprogram.serializer.ProgramsJsonDeserializer
has no default (no arg) constructor"
(Adding a no arg constructor gives the error that StdDeserializer does not have a default constructor.) (添加no arg构造函数会导致错误,指出StdDeserializer没有默认的构造函数。)
Is this the correct approach to achieving what I am trying to do? 这是实现我想要做的正确方法吗? And does anyone know why I get this error message?
有人知道我为什么收到此错误消息吗?
I want to omit any structures that have "exists" set to false during the deserialization process so that no POJO is ever created for them.
我想在反序列化过程中忽略“存在”设置为false的任何结构,这样就不会为它们创建POJO。
I think your objective is to retrieve a list of Programs
instance that only have exists
set to true
after derserialization. 我认为您的目标是检索在反序列化之后仅
exists
设置为true
的Programs
实例列表。 A customized CollectionDeserializer
to filter those unwanted instance may help: 定制的
CollectionDeserializer
可以过滤那些不需要的实例,这可能会有所帮助:
public class ProgramsCollectionHandler extends SimpleModule {
private static class ProgramsCollectionDeserializer extends CollectionDeserializer {
public ProgramsCollectionDeserializer(CollectionDeserializer deserializer) {
super(deserializer);
}
private static final long serialVersionUID = 1L;
@Override
public Collection<Object> deserialize(JsonParser parser, DeserializationContext context)
throws IOException, JsonProcessingException {
Collection<Object> result = super.deserialize(parser, context);
Collection<Object> filteredResult = new ArrayList<Object>();
for (Object o : result) {
if (o instanceof Programs) {
final Programs programs = (Programs) o;
if (programs.exists) {
filteredResult.add(programs);
}
}
}
return filteredResult;
}
@Override
public CollectionDeserializer createContextual(
DeserializationContext context,
BeanProperty property) throws JsonMappingException {
return new ProgramsCollectionDeserializer(super.createContextual(context, property));
}
}
private static final long serialVersionUID = 1L;
@Override
public void setupModule(Module.SetupContext context) {
super.setupModule(context);
context.addBeanDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<?> modifyCollectionDeserializer(
DeserializationConfig config, CollectionType type,
BeanDescription beanDesc, JsonDeserializer<?> deserializer) {
if (deserializer instanceof CollectionDeserializer) {
return new ProgramsCollectionDeserializer(
(CollectionDeserializer) deserializer);
}
return super.modifyCollectionDeserializer(config, type,
beanDesc, deserializer);
}
});
}
}
After that, your can register it into your object mapper: 之后,您可以将其注册到对象映射器中:
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(new ProgramsCollectionHandler());
"Can not deserialize instance of java.util.ArrayList out of START_OBJECT token" message was "Class com.myprogram.serializer.ProgramsJsonDeserializer has no default (no arg) constructor" (Adding a no arg constructor gives the error that StdDeserializer does not have a default constructor.)
“无法从START_OBJECT令牌中反序列化java.util.ArrayList的实例”消息是“类com.myprogram.serializer.ProgramsJsonDeserializer没有默认(无arg)构造函数”(添加无arg构造函数会给出StdDeserializer没有的错误默认构造函数。)
This may be because your constructor cannot be accessed. 这可能是因为无法访问您的构造函数。 For example, your deserializer is implemented as a non-static inner class.
例如,您的解串器被实现为非静态内部类。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.