反序列化 json 对 java 中自定义枚举值的响应

Deserializing json response to custom enum value in java

我正在尝试使用自定义枚举值反序列化 JSON 响应,但不是使用自定义值进行映射,而是使用其序号值设置枚举。我进行了很多搜索,但无法弄清楚自己做错了什么。任何帮助都会很棒。

响应是

{"id":12, "status":1}

对应的枚举对象和枚举是

public class Car {
   int id;
   CarStatus status;
}


public enum CarStatus {
    
    READY(1),
    WAITING(2);

    private int value;

    CarStatus(int value) {
        this.value = value;
    }

    @JsonValue
    public int getValue() {
        return value;
    }

}

状态设置为WAITING,但我希望它设置为READY

当仅结合 @JsonValue 注释使用整数时,这似乎是枚举的一个已知问题。 Github 上有一些未解决的问题(例如 1 and 2),目前计划在 2.13 版中使用。

同时,你可以通过添加一个 @JsonCreator 来解决这个问题,其中 returns 对应 CarStatus:

public enum CarStatus {

    READY(1),
    WAITING(2);

    private final int value;

    CarStatus(int value) {
        this.value = value;
    }

    @JsonValue
    public int getValue() {
        return this.value;
    }

    @JsonCreator
    public static CarStatus getByValue(int value) {
        for (CarStatus status : values()) {
            if (status.value == value) {
                return status;
            }
        }
        return null;
    }
}

要测试的代码:

ObjectMapper objectMapper = new ObjectMapper();

Car original = new Car();
original.setId(45);
original.setStatus(CarStatus.READY);

String json = objectMapper.writeValueAsString(original);

Car reconstruction = objectMapper.readValue(json, Car.class);

System.out.println(json);
System.out.println(reconstruction.getStatus());

输出:

{"id":45,"status":1}
READY

你的枚举错过了@JsonCreator

这样试试:

public enum CarStatus {
    
    READY(1),
    WAITING(2);

    private int value;

    CarStatus(int value) {
        this.value = value;
    }

    @JsonValue
    public int getValue() {
        return value;
    }

    @JsonCreator
    public static CarStatus getItem(int code){
        for(CarStatus item : values()){
            if(item.getValue() == code){
                return item;
            }
        }
        return null;
    }
}

你可以在github中看到我的代码:https://github.com/onemaomao/java-common-mistakes/tree/master/src/main/java/org/geekbang/time/questions/Whosebug/reslove/q1