从 Java 中的 Integer 和 String 反序列化枚举

Deserialize enum from both Integer and String in Java

我正在添加新的代码逻辑,使用 CDC(捕获数据更改)事件。 来自数据库的 status 字段表示为一个 int,应该反序列化为一个枚举。 这是枚举:

public enum Status {

    ACTIVE(21),
    CANCELLED(22),
    EXPIRED(23),
    FAILED(24),
    PAUSED(25);

    private static final Map<Integer, Status> map = new HashMap<>();

    static {
        for (val value : Status.values()) {
            if (map.put(value.getId(), value) != null) {
                throw new IllegalArgumentException("duplicate id: " + value.getId());
            }
        }
    }

    public static Status getById(Integer id) {
        return map.get(id);
    }

    private Integer id;

    Status(Integer id) {
        this.id = id;
    }

    public Integer getId() {
        return id;
    }
}
  1. 枚举不能从 Integer 中“开箱即用”地序列化,因为它 不是从 0 开始(收到 index value outside legal index range 异常)。
  2. 今天我们已经有了一个接收字符串(例如“ACTIVE”)并成功反序列化的流程。我不想change/harm这个能力。

我尝试在此处添加 @JsonCreator

@JsonCreator
public static SubscriptionStatus getById(Integer id) {
    return map.get(id);
}

但是现在无法反序列化String了。我更喜欢有一个简单的解决方案,而不是为其创建自定义反序列化器(我认为应该有一个)。

尝试这样的事情:

@JsonCreator
public static Status get(Object reference) {
  if( reference instanceof Number num) {
    return getById(num.intValue());
  } else if( reference instanceof String str) {
    //the string might contain the id as well, e.g. "21" for ACTIVE
    //so you might want to check the string for this, if this is expected
    return Enum.valueOf(Status.class, str);
  }
        
  return null;
}

这基本上采用任何类型的值,检查它是什么并相应地解析枚举值。