我有一个将 JSON 对象映射到 POJO 的类。 POJO 中的字段之一是枚举,该枚举具有带注释的值
@JsonEnumDefaultValue
这意味着,如果 JSON 文件包含不属于枚举的值,则会将该字段设置为默认值。
我想在 POJO 中添加一个名为
originalValue
的新字段。在这里我想设置文件中存在的实际值。输入文件无法修改。
我假设我需要为枚举字段编写一个自定义反序列化器,但我无法弄清楚如何在原始类实例中设置该值。
枚举:
public enum Status {
Success,
Failure,
@JsonEnumDefaultValue
Unknown
}
波乔:
public class Report {
Status status;
String inputStatus; //Set this field to actual value passed.
}
文件输入:
{
"status": "garbage"
}
预期Pojo:
{
"status": "Unknown",
"inputStatus": "garbage"
}
我可以想到以下解决方案:
public class MyMappingTest {
public enum Status {
Success,
Failure,
Unknown;
public static Status valueOfElseNull(String s) {
for (Status value : values()) {
if (value.name().equalsIgnoreCase(s)) {
return value;
}
}
return null;
}
}
public static class Report {
Status status;
String inputStatus;
public void setStatus(String status) {
this.inputStatus = status;
this.status = Optional.ofNullable(Status.valueOfElseNull(status)).orElse(Status.Unknown);
}
}
@Test
void testMapping() throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
Report report = objectMapper.readValue("""
{
"status": "garbage"
}
""", Report.class);
Assertions.assertThat(report.inputStatus).isEqualTo("garbage");
Assertions.assertThat(report.status).isEqualTo(Status.Unknown);
}
}
Jackson 使用 setter 从 JSON 构造 POJO。因此,我可以创建一个 setter(可以选择用
@JsonSetter
对其进行注释,以提示 Jackson 我想要在此 setter 中为其提供值的字段,但这里没有必要,因为字段的名称可以从 setter 方法中扣除)接受String
,然后做我想做的事。所以我认为自定义解串器在这里可能有点重型武器,有一个更简单的路径。