Java 对象映射器反序列化器根据另一个字段的值设置字段的值

问题描述 投票:0回答:1

我有一个将 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"
}
java jackson
1个回答
0
投票

我可以想到以下解决方案:

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
,然后做我想做的事。所以我认为自定义解串器在这里可能有点重型武器,有一个更简单的路径。

© www.soinside.com 2019 - 2024. All rights reserved.