Jackson 2.11.4:为缺少的 JSON 字段设置默认值
Jackson 2.11.4: Set Default Value For Missing JSON field
我有以下JSON
"Choices": [
{
"choiceId": "1"
},
{
"choiceId": "2",
"choiceType": null
}
]
下面是 POJO,我需要两个构造函数,因为如果 json 中没有 choiceType
,我需要将其默认为 Yes
,如果 choiceType
在 json 中存在 null
值,那么它不应默认为 Yes
@Getter
@ToString
@Setter
@NoArgsConstructor
public class Choices {
@JsonProperty("choiceId")
@NonNull
private String choiceId;
@JsonProperty("choiceType")
private String choiceType;
@JsonCreator
@JsonIgnoreProperties(ignoreUnknown = true)
public Choices(@JsonProperty("choiceId") String choiceId) {
this.choiceType = choiceType !=null ? choiceType : "Yes";
this.choiceId = choiceId;
}
public Choices(@JsonProperty("choiceId") String choiceId, @JsonProperty("choiceType") String choiceType) {
this.choiceType = choiceType;
this.choiceId = choiceId;
}
}
我的目标是在上面的Json被反序列化并且我有下面的测试用例
时有一个选择列表
@Test
public void testChoices(){
ObjectMapper objectMapper = new ObjectMapper();
String json = "[ { \"choiceId\": \"1\" }, { \"choiceId\": \"2\", \"choiceType\": null } ]";
List<Choices> choices = objectMapper.convertValue(json, new TypeReference<List<Choices>>() {
});
assertTrue(choices.get(0).getChoiceId().equals("1"));
assertTrue(choices.get(0).getChoiceType().equals("Yes"));
assertTrue(choices.get(1).getChoiceType().equals("2"));
assertNull(choices.get(1).getChoiceType());
}
当我尝试反序列化以下内容时 json。我已经尝试了很多解决方案,但仍然没有成功,有人可以帮我解决这个问题吗?
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Invalid definition for property `choiceType` (of type `com.onetrust.ds.request.dto.rest.Choices`): Could not find creator property with name 'choiceType' (known Creator properties: [choiceId])
at [Source: UNKNOWN; line: -1, column: -1]
看起来你的问题是你应该用@JsonCreator
标记两个构造函数。而且你只需要其中之一,Jackson 将默认将不设置值填充为 null
(无需为此创建单独的构造函数)。
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import lombok.Getter;
public static void main(String[] args) throws IOException {
String json = "[ { \"choiceId\": \"1\" }, { \"choiceId\": \"2\", \"choiceType\": null } ]";
ObjectMapper mapper = new ObjectMapper();
ObjectReader reader = mapper.readerFor(Choices.class);
List<Choices> choices = reader.<Choices>readValues(json).readAll();
}
@Getter
public static class Choices {
private String choiceId;
private String choiceType;
@JsonCreator
public Choices(@JsonProperty("choiceId") String choiceId,
@JsonProperty("choiceType") String choiceType) {
this.choiceId = choiceId;
this.choiceType = choiceType == null ? "Yes" : choiceType;
}
}
我找到了这个例子here
您可以删除 args 构造函数并将值默认为“是”。如果 value 显式设置为 null 或一个值,它将被分配。如果缺少值,它将被默认。
@Getter
@ToString
@Setter
@NoArgsConstructor
public class Choices {
@JsonProperty("choiceId")
@NonNull
private String choiceId;
@JsonProperty("choiceType")
private String choiceType = "Yes";
}
参考 - Jackson: What happens if a property is missing?
我有以下JSON
"Choices": [
{
"choiceId": "1"
},
{
"choiceId": "2",
"choiceType": null
}
]
下面是 POJO,我需要两个构造函数,因为如果 json 中没有 choiceType
,我需要将其默认为 Yes
,如果 choiceType
在 json 中存在 null
值,那么它不应默认为 Yes
@Getter
@ToString
@Setter
@NoArgsConstructor
public class Choices {
@JsonProperty("choiceId")
@NonNull
private String choiceId;
@JsonProperty("choiceType")
private String choiceType;
@JsonCreator
@JsonIgnoreProperties(ignoreUnknown = true)
public Choices(@JsonProperty("choiceId") String choiceId) {
this.choiceType = choiceType !=null ? choiceType : "Yes";
this.choiceId = choiceId;
}
public Choices(@JsonProperty("choiceId") String choiceId, @JsonProperty("choiceType") String choiceType) {
this.choiceType = choiceType;
this.choiceId = choiceId;
}
}
我的目标是在上面的Json被反序列化并且我有下面的测试用例
时有一个选择列表@Test
public void testChoices(){
ObjectMapper objectMapper = new ObjectMapper();
String json = "[ { \"choiceId\": \"1\" }, { \"choiceId\": \"2\", \"choiceType\": null } ]";
List<Choices> choices = objectMapper.convertValue(json, new TypeReference<List<Choices>>() {
});
assertTrue(choices.get(0).getChoiceId().equals("1"));
assertTrue(choices.get(0).getChoiceType().equals("Yes"));
assertTrue(choices.get(1).getChoiceType().equals("2"));
assertNull(choices.get(1).getChoiceType());
}
当我尝试反序列化以下内容时 json。我已经尝试了很多解决方案,但仍然没有成功,有人可以帮我解决这个问题吗?
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Invalid definition for property `choiceType` (of type `com.onetrust.ds.request.dto.rest.Choices`): Could not find creator property with name 'choiceType' (known Creator properties: [choiceId])
at [Source: UNKNOWN; line: -1, column: -1]
看起来你的问题是你应该用@JsonCreator
标记两个构造函数。而且你只需要其中之一,Jackson 将默认将不设置值填充为 null
(无需为此创建单独的构造函数)。
import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectReader;
import lombok.Getter;
public static void main(String[] args) throws IOException {
String json = "[ { \"choiceId\": \"1\" }, { \"choiceId\": \"2\", \"choiceType\": null } ]";
ObjectMapper mapper = new ObjectMapper();
ObjectReader reader = mapper.readerFor(Choices.class);
List<Choices> choices = reader.<Choices>readValues(json).readAll();
}
@Getter
public static class Choices {
private String choiceId;
private String choiceType;
@JsonCreator
public Choices(@JsonProperty("choiceId") String choiceId,
@JsonProperty("choiceType") String choiceType) {
this.choiceId = choiceId;
this.choiceType = choiceType == null ? "Yes" : choiceType;
}
}
我找到了这个例子here
您可以删除 args 构造函数并将值默认为“是”。如果 value 显式设置为 null 或一个值,它将被分配。如果缺少值,它将被默认。
@Getter
@ToString
@Setter
@NoArgsConstructor
public class Choices {
@JsonProperty("choiceId")
@NonNull
private String choiceId;
@JsonProperty("choiceType")
private String choiceType = "Yes";
}
参考 - Jackson: What happens if a property is missing?