【问题标题】:Deserializing json response to custom enum value in java反序列化对java中自定义枚举值的json响应
【发布时间】:2021-01-14 08:11:53
【问题描述】:

我正在尝试使用自定义枚举值反序列化 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

【问题讨论】:

    标签: java jackson fasterxml


    【解决方案1】:

    你的枚举错过了@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/stackoverflow/reslove/q1

    【讨论】:

    • 不建议使用枚举来跨服务传输,因为版本控制问题以及反序列化在序列化方面很复杂且容易出错。因此,我只推荐在内部程序中使用枚举。
    【解决方案2】:

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

    与此同时,您可以通过添加@JsonCreator 来解决此问题,该@JsonCreator 返回相应的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
    

    【讨论】:

      猜你喜欢
      • 2013-09-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-29
      • 1970-01-01
      • 2013-07-17
      • 1970-01-01
      • 2014-12-12
      • 1970-01-01
      相关资源
      最近更新 更多