如何忽略杰克逊反序列化的空字段并使用默认值?

问题描述 投票:0回答:1

我的

@RequestBody
课程看起来像这样:

data class UpsertDataDto(
    @field:JsonProperty("pages")
    @JsonInclude(JsonInclude.Include.NON_NULL)
    val links: List<Long> = emptyList()
)

我想避免

null
字段出现
links
情况下的错误,因此我使用
@JsonInclude(JsonInclude.Include.NON_NULL)
注释和默认值
emptyList()
。但是当我发送带有 null 的请求时,我得到这样的异常:

Resolved [org.springframework.http.converter.HttpMessageNotReadableException: 
JSON parse error: Instantiation of [simple type, class com.life.app.domain.dto.request.UpsertDataDto] 
value failed for JSON property links due to missing (therefore NULL) 
value for creator parameter synonyms which is a non-nullable type; 
nested exception is com.fasterxml.jackson.module.kotlin.MissingKotlinParameterException: 
Instantiation of [simple type, class com.life.app.domain.dto.request.UpsertDataDto] value 
failed for JSON property links due to missing (therefore NULL) value for creator parameter links 
which is a non-nullable type<EOL> at 
[Source: (org.springframework.util.StreamUtils$NonClosingInputStream); line: 422, column: 1] 
(through reference chain: com.life.app.domain.dto.request.UpsertDataDto["pages"]->java.util.ArrayList[38]->
com.life.app.domain.dto.request.UpsertDataDto["links"])]

我用于测试的Json

{
    "links": null
}
json kotlin jackson
1个回答
0
投票

不幸的是,默认值永远不会适用于此。我在 Gson 上遇到了类似的问题,但我认为 Jackson 的工作原理是一样的。它从不调用默认构造函数,因此从不应用默认值。它使用称为

UnsafeAllocator
的东西创建数据类的实例。关于 Gson 的更全面的解释可以阅读here

但幸运的是,在那篇文章中提到杰克逊对此有一个解决方案。引用:

对于这种情况,杰克逊有一个很好的解决方案。它有两个特殊的注解:@JsonCreator和@JsonProperty

这是如何使用它们的示例(文章链接):

public class NonDefaultBean {
    private final String name;
    private final int age;

    private String type;

    @JsonCreator
    public NonDefaultBean(@JsonProperty("name") String name, @JsonProperty("age") int age)
    {
        this.name = name;
        this.age = age;
    }

    public void setType(String type) {
        this.type = type;
    }
}

在这种情况下,将不会使用 Unsafe。而不是那种糟糕的方法(这里是示例链接,为什么会这样),将调用普通的构造函数 NonDefaultBean(String name, intage) 。

尽管这是一个java示例,它也不是一个数据类。我不完全确定您是否可以在 kotlin 中执行相同的操作,或者您是否需要将其设为普通类而不是数据类。但希望你能解决。

© www.soinside.com 2019 - 2024. All rights reserved.