gpt4 book ai didi

java - jackson 将不同的字符串反序列化为相同的枚举常量

转载 作者:搜寻专家 更新时间:2023-11-01 03:16:38 24 4
gpt4 key购买 nike

假设我有一个如下所示的 enum Status

public enum Status {
SUCCESS,
FAIL,
RETRY,
UNKNOWN
}

我正在从 JSON 中接收 status 属性,它可能类似于以下示例。

  • {"status":"success"}//有效情况,反序列化为 Status.SUCCESS
  • {"status":"fail"}//有效情况,反序列化为Status.FAIL
  • {"status":"retry"}//有效情况,反序列化为 Status.RETRY

但任何其他值都应反序列化为 Status.UNKNOWN。示例。

  • {"status":"blabla"}//大小写无效,反序列化为Status.UNKNOWN
  • {"status":"John"}//大小写无效,反序列化为 Status.UNKNOWN

我知道我可以通过编写自定义反序列化器来做到这一点,但我会尽量避免这种情况,因为我的程序中有很多很多枚举,并且为每个枚举都要求一个自定义反序列化器会有点矫枉过正。

理想情况下,正则表达式中的某种构造函数可以匹配任何字符串(“成功”、“失败”和“重试”除外)。

有没有一种方法可以在不编写自定义反序列化器的情况下使用 Jackson 来实现?

最佳答案

如果您所有的枚举都有 UNKNOWN 值,您可以像这样编写一个自定义反序列化器:

class EnumDeserializer extends JsonDeserializer<Enum> {

private final Class<? extends Enum> enumType;

public EnumDeserializer(Class<? extends Enum> enumType) {
this.enumType = enumType;
}

@Override
public Enum deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException {
try {
String stringValue = jp.getValueAsString().toUpperCase();
return Enum.valueOf(enumType, stringValue.toUpperCase());
} catch (IllegalArgumentException e) {
return Enum.valueOf(enumType, "UNKNOWN");
}
}
}

并配置您的映射器以使用它:

SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new BeanDeserializerModifier() {
@Override
public JsonDeserializer<Enum> modifyEnumDeserializer(DeserializationConfig config,
final JavaType type,
BeanDescription beanDesc,
final JsonDeserializer<?> deserializer) {

return new EnumDeserializer((Class<Enum<?>>) type.getRawClass());
}
});

ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);

或者,您可以使用 jackson 反序列化功能为未知枚举属性设置默认值:

enum MyEnum { A, B, @JsonEnumDefaultValue UNKNOWN }
...
final ObjectMapper mapper = new ObjectMapper();
mapper.enable(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_USING_DEFAULT_VALUE);

MyEnum value = mapper.readValue("\"foo\"", MyEnum.class);
assertSame(MyEnum.UNKNOWN, value);

但使用这种方法,您需要更改所有枚举以使用 @JsonEnumDefaultValue 注释作为默认值,而且默认情况下它不处理小写枚举值。

关于java - jackson 将不同的字符串反序列化为相同的枚举常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47951187/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com