java - 如何忽略导致 jackson 反序列化错误的列表条目?

标签 java error-handling jackson json-deserialization jackson-databind

我正在尝试使用 Jackson 反序列化 JSON 结构,并且正在使用如下所示的 DTO:

public class RootLevelDTO {
   
    private List<ComplexEntry> complexEntries;
    // ... other fields, not relevant

}

现在,ComplexEntry可以有子类型,那些有枚举类型的属性等等。如果通信的另一方更新他们的 API,例如添加另一个子类型或添加枚举文字。

我想做的是告诉 jackson :

  • 如果您在 complexEntries 反序列化过程中遇到任何数据绑定(bind)错误领域...
  • ...不要抛出异常,而是忽略此条目并继续下一个条目。

到目前为止我尝试的是使用 ComplexEntry 的委托(delegate)解串器:

public class ComplexEntryDeserializer extends StdDeserializer<ComplexEntry> {

    private StdDeserializer<ComplexEntry> delegate;

    public ComplexEntryDeserializer(StdDeserializer<ComplexEntry> delegate){
        this.delegate = delegate;
    }

    public ComplexEntry deserialize(JsonParser p, DeserializationContext ctxt){
        try {
            return this.delegate.deserialize(p, ctxt);
        }catch(Exception e){
            // the list entry failed to deserialize, but we have to return *something* here
            return null;
        }
    }
    
    // ... other mandatory methods, not relevant here
}

这个解决方案有一个问题,它会引入nullcomplexEntries列表,然后我必须使用 Converter 显式删除它.

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

最佳答案

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

DTO:

public class RootLevelDTO {

    // use a custom deserializer for the list
    @JsonDeserialize(using = ListOfComplexEntryDeserializer.class)
    private List<ComplexEntry> complexEntries;

}

解串器:

public class ListOfComplexEntryDeserializer extends JsonDeserializer<List<ComplexEntry>> {

    @Override
    public List<ComplexEntry> deserialize(JsonParser p, DeserializationContext ctxt) {
        List<ComplexEntry> resultList = new ArrayList<>();
        while(p.nextToken() != JsonToken.END_ARRAY){
            try {
                // delegate the deserialization of the individual list entries to the standard deserializers
                resultList.add(ctxt.readValue(p, ComplexEntry.class))
            }catch(Exception e){
                // log that the entry wasn't deserialized properly
                System.out.println("ComplexEntry could not be read and will be ignored.");
            }
        }
        return resultList;
    }

}

重要免责声明:虽然上面的代码可以工作,但您不应该在设计上追求它。我真的已经陷入困境,别无选择(由于我无法控制的外部因素),对于这种情况,它是有效的。

关于java - 如何忽略导致 jackson 反序列化错误的列表条目?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63559544/

相关文章:

java - ObjectMapper 必须使用 JSON 文件未提供的参数调用构造函数

java - 在 Json Resteasy 上处理集合(多对多)的递归引用

java - 将 MySQL Server 数据库导出到文件

java - JSF:操作调用被延迟

haskell - 在Haskell中使用ErrorT

java - Base 64 编码问题 (MIME-NO-LINEFEEDS)

java - 如何对变量值进行排序,然后按从大到小的顺序打印它们?

java - AWS 自定义 CloudWatch 指标 - 按 Auto-Scaling 组聚合

exception - 在哪里捕获此错误?

ios - 如何正确实现 UIWebView 'didFailLoadWithError' 警报 View ?