Java 如何在Jackson中忽略导致反序列化错误的列表项?

Java 如何在Jackson中忽略导致反序列化错误的列表项?,java,error-handling,jackson,json-deserialization,jackson-databind,Java,Error Handling,Jackson,Json Deserialization,Jackson Databind,我正在尝试用Jackson反序列化JSON结构,我正在使用一个DTO,它看起来像这样: 公共类RootLevelDTO{ 私有列表复杂入口; //…其他字段,不相关 } 现在,ComplexEntry可以有子类型,这些子类型具有枚举类型的属性等。如果通信的另一方更新其API,例如添加另一个子类型或添加枚举文本,则此处可能会出现很多错误 我想做的是告诉杰克逊: 如果在反序列化complexEntries字段期间遇到任何数据绑定错误 。。。不要抛出异常,而是忽略此条目并继续下一个条目 到目前为

我正在尝试用Jackson反序列化JSON结构,我正在使用一个DTO,它看起来像这样:

公共类RootLevelDTO{
私有列表复杂入口;
//…其他字段,不相关
}
现在,
ComplexEntry
可以有子类型,这些子类型具有枚举类型的属性等。如果通信的另一方更新其API,例如添加另一个子类型或添加枚举文本,则此处可能会出现很多错误

我想做的是告诉杰克逊:

  • 如果在反序列化
    complexEntries
    字段期间遇到任何数据绑定错误
  • 。。。不要抛出异常,而是忽略此条目并继续下一个条目
到目前为止,我尝试为
ComplexEntry
使用一个委托反序列化程序:

public类ComplexEntryDeserializer扩展StdDeserializer{
私有stdder序列化委托;
公共ComplexEntryDeserializer(StdDeserializer委托){
this.delegate=委托;
}
公共ComplexEntry反序列化(JsonParser,反序列化上下文ctxt){
试一试{
返回this.delegate.deserialize(p,ctxt);
}捕获(例外e){
//列表项未能反序列化,但我们必须在此处返回*something*
返回null;
}
}
//…其他强制性方法,此处不适用
}
此解决方案存在的问题是,它将向
complexEntries
列表引入
null
值,然后我必须使用
转换器显式地消除这些值


这个问题有更优雅的解决方案吗?

经过大量的修补,我最终得到了以下解决方案。它不需要任何额外的jackson模块或其他魔法,只需要一个(特定的)反序列化器

DTO:

公共类RootLevelDTO{
//对列表使用自定义反序列化程序
@JsonDeserialize(使用=ListOfComplexEntryDeserializer.class)
私有列表复杂入口;
}
反序列化程序:

complexentrydeserializer的公共类列表扩展了JsonDeserializer{
@凌驾
公共列表反序列化(JSONP,反序列化上下文ctxt){
List resultList=new ArrayList();
while(p.nextToken()!=JsonToken.END_数组){
试一试{
//将单个列表项的反序列化委托给标准反序列化程序
添加(ctxt.readValue(p,ComplexEntry.class))
}捕获(例外e){
//记录条目未正确反序列化
System.out.println(“无法读取ComplexEntry,将被忽略。”);
}
}
返回结果列表;
}
}

大免责声明:虽然上面的代码有效,但它不是你应该设计的东西。我在这里真的是束手无策,别无选择(由于我无法控制的外部因素),在这种情况下,它是有效的。

这听起来像是一个错误,即你选择了错误的解决方案,走错了路。听起来你真的需要告诉Jackson:“如果你遇到任何未知的属性,只需在一个通用的
映射中捕获它们。”。解析将永远不会失败,并且所有(未知)数据都被正确解析。例如,请参见Baeldung的文章“Jackson注释示例”。@Andreas通用对象不起作用。我的DTO中的字段有明确定义的Java类型(对象、枚举、这些类型的列表)。Jackson无法尝试为枚举字段分配任何值,该枚举的文本除外-JVM将不允许这样做,这是理所当然的。请后退一步,思考问题本身:如果api更新,您是否真的希望(静默)忽略任何未知类型或属性?在某种程度上,这些不是相关的吗?还有,谁是api的所有者?是你还是对方?是的,绝对是,这正是我想要做的。它不是关于某些物体的未知属性;通过设置,杰克逊可以很容易地忽略这些。我正在处理未知的子类型和未知的枚举文本。我不希望Jackson在发生这种情况时崩溃,它应该忽略列表项。好吧,如果你真的需要这样做,你可以尝试在dto中提供一个修饰的、最终的列表,忽略空值。如果我没记错的话,只为这样的列表提供一个getter应该会让Jackson使用该实例来添加反序列化元素。这里有一个类似的解决方案,是由Jackson的一个家伙发布的:-主要的区别是他们使它通用。