我的
@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
}
不幸的是,默认值永远不会适用于此。我在 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 中执行相同的操作,或者您是否需要将其设为普通类而不是数据类。但希望你能解决。