问题:如何使用简洁/惯用的现代Java从接收到的JSON中捕获(可选)List字段media_links_txt
,将其作为null或其实际值?
功能愿望是:
- 一些属性具有显式的
@JsonGetter
和@JsonSetter
字段名,因为Record同时用作反序列化目标和响应模型(API客户端要求不同的字段名作为传入JSON) optionalStuff
字段是…well可选地存在于反序列化流中
代码如下:
import com.fasterxml.jackson.annotation.*;
import org.springframework.lang.NonNull;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
public record TestResponse(@NonNull Response response) {
@JsonIgnoreProperties(ignoreUnknown = true)
public record Response(@NonNull List<Doc> docs,
@NonNull Integer numFound,
@NonNull Integer start) {
public record Doc(@NonNull String id,
@NonNull @JsonGetter("content_t") @JsonSetter("content") String content,
@NonNull @JsonGetter("title_t") @JsonSetter("title") String title,
@JsonGetter("media_links_txt") @JsonSetter("mediaLinks") List<String> mediaLinks) {
}
}
}
当这段代码接收到如下所示的JSON时:
{
"response" : {
"docs" : [ {
"content_t" : "Test content 1",
"title_t" : "Test title 1",
"media_links_txt" : [ "d7810883-42de-4280-a286-5bb14e517ce3", "fa60db0a-0e28-4c9c-8092-4eafe57251cd" ],
"id" : "54870dc265c855c516bcd0a2f93f2267"
}, {
"content_t" : "Test content 2",
"title_t" : "Test content 2",
"id" : "a4a38aa64427d63aab0c4412eb659586"
} ],
"numFound" : 2,
"start" : 0
}
它会产生以下错误信息:Should never call set() on setterless property
并指向media_links_txt
。这让我很困惑。。
- 记录一开始没有setter,所以它尝试使用构造函数,我目前认为这是好的和理想的(它可以被分配一个
null
值,因为mediaLinks
是我认为我已经写的) - 但是它可以构造
docs
字段(也是List)而没有问题吗?
所以我尝试用下面的代码欺骗它(也许它需要一个非默认类型)
import com.fasterxml.jackson.annotation.*;
import org.springframework.lang.NonNull;
import java.util.List;
@JsonIgnoreProperties(ignoreUnknown = true)
public record TestResponse(@NonNull Response response) {
@JsonIgnoreProperties(ignoreUnknown = true)
public record Response(@NonNull List<Doc> docs,
@NonNull Integer numFound,
@NonNull Integer start) {
public record Doc(@NonNull String id,
@NonNull @JsonGetter("content_t") @JsonSetter("content") String content,
@NonNull @JsonGetter("title_t") @JsonSetter("title") String title,
@JsonGetter("media_links_txt") @JsonSetter("mediaLinks") List<StringClone> mediaLinks) {
public record StringClone(@NonNull String mediaLinksRetry) {
}
}
}
}
其抛出:Cannot construct instance of StringClone (although at least one Creator exists): no String-argument constructor/factory method to deserialize from String value ('d7810883-42de-4280-a286-5bb14e517ce3')
- 等等...只有String的记录上没有String参数构造函数?我相当肯定应该有,但我可能错过了一些东西,并希望学习这样!
问题:如何使用简洁/惯用的现代Java从接收到的JSON中捕获(可选)List字段media_links_txt
,作为null或其实际值?
使用的版本为:
- jackson-databind 2.13.5
- Spring框架5.3.27(通过 Spring Boot 启动器2.7.11)
我认为https://github.com/FasterXML/jackson-databind/issues/2692可能描述了这个问题,但到目前为止还没有合适的解决方法。
1条答案
按热度按时间dohp0rv51#
JsonSetter
s中的value参数需要与JSON中的字段名匹配。我假设Jackson认识到该类型是一条记录,并且如果ctor参数名称与JSON字段名称一致,则能够调用构造函数。也就是说,如果你像这样修改
JsonSetter
注解:那它似乎起作用了,至少对我来说是这样。这可以通过将
JsonGetter
/JsonSetter
对替换为单个JsonProperty
注解来进一步简化: