问题:如何使用简洁/惯用的现代 Java 将接收到的 JSON 中的(可选)列表字段
media_links_txt
捕获为 null 或其实际值?
功能愿望是:
@JsonGetter
和 @JsonSetter
字段名称,因为 Record 既用作反序列化目标又用作响应模型(API 客户端需要不同的字段名称作为传入 JSON)optionalStuff
字段......可以选择出现在反序列化流程中代码如下:
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
。这让我很困惑...
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')
问题:如何使用简洁/惯用的现代 Java 将接收到的 JSON 中的(可选)列表字段
media_links_txt
捕获为 null 或其实际值?
使用的版本是:
我认为https://github.com/FasterXML/jackson-databind/issues/2692可能描述了这个问题,但目前还没有适当的解决方法。
JsonSetter
中的值参数需要与 JSON 中的字段名称匹配。我假设 Jackson 认识到该类型是一条记录,并且如果 ctor 参数名称与 JSON 字段名称对齐,则能够调用构造函数。
即,如果您像这样更改
JsonSetter
注释:
public record Doc(String id,
@JsonGetter("content_t") @JsonSetter("content_t") String content,
@JsonGetter("title_t") @JsonSetter("title_t") String title,
@JsonGetter("media_links_txt") @JsonSetter("media_links_txt") List<String> mediaLinks) {
}
然后它似乎起作用了,至少对我来说是这样。这可以通过用单个
JsonGetter
注释替换 JsonSetter
/JsonProperty
对来进一步简化:
public record Doc(String id,
@JsonProperty("content_t") String content,
@JsonProperty("title_t") String title,
@JsonProperty("media_links_txt") List<String> mediaLinks) {
}
在记录上配置此注释应该可以使其工作:
@JsonAutoDetect(fieldVisibility = ANY, getterVisibility = ANY, setterVisibility = ANY, creatorVisibility = ANY)