【问题标题】:Deserialization of Enum does not work - Jackson [duplicate]枚举的反序列化不起作用 - Jackson [重复]
【发布时间】:2017-12-01 01:59:41
【问题描述】:

我尝试序列化和反序列化枚举。但是杰克逊使用自然枚举顺序值而不是我的。

我使用杰克逊 2.8.9。

我的测试枚举:

public enum SomeEnum {

    SOME_VAL1(1),

    SOME_VAL2(2),

    SOME_VAL3(3),

    SOME_VAL4(4);

    private final Integer code;

    @JsonCreator
    SomeEnum(@JsonProperty("code") Integer code) {
        this.code = code;
    }

    @JsonValue
    public Integer getCode() {
        return code;
    }

}

这是我测试失败的完整代码:

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonValue;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.io.IOException;

public class Program {

    public enum SomeEnum {

        SOME_VAL1(1),

        SOME_VAL2(2),

        SOME_VAL3(3),

        SOME_VAL4(4);

        private final Integer code;

        @JsonCreator
        SomeEnum(@JsonProperty("code") Integer code) {
            this.code = code;
        }

        @JsonValue
        public Integer getCode() {
            return code;
        }

    }

    public static class EnumWrapper {

        private final SomeEnum someEnumVal;

        public EnumWrapper(@JsonProperty("someEnum") SomeEnum someEnumVal) {
            this.someEnumVal = someEnumVal;
        }

        @JsonProperty("someEnum")
        public SomeEnum getSomeEnumVal() {
            return someEnumVal;
        }
    }

    public static void main(String[] args) throws IOException {

        ObjectMapper mapper = new ObjectMapper();

        String inputJson = mapper.writeValueAsString(new EnumWrapper(SomeEnum.SOME_VAL3));
        EnumWrapper resultEnumWrapper =
                mapper.readValue(inputJson, EnumWrapper.class);

        if (resultEnumWrapper.getSomeEnumVal() != SomeEnum.SOME_VAL3) {
            System.out.println(resultEnumWrapper.getSomeEnumVal());
            System.out.println(inputJson);
            throw new RuntimeException("enum = " + resultEnumWrapper.getSomeEnumVal());
        }
    }
}

为什么我有这个错误的枚举反序列化?我使用@JsonProperty

【问题讨论】:

  • 你不能在枚举定义之外调用枚举构造函数,所以@JsonCreator 是没用的。请尝试使用静态工厂方法。
  • @shmosel jackson 使用带有帮助反射的构造函数。
  • 不能通过反射或任何其他方式从外部构造枚举实例。

标签: java serialization enums jackson deserialization


【解决方案1】:

尝试使用@JsonCreator 公开方法,例如:

@JsonCreator
public static SomeEnum findByCode(final int code){
    for (final SomeEnum element : values()) {
        if (element.getCode().equals(code)) {
            return element;
        }
    }
    return null;
}

【讨论】:

  • 它可以工作,但有一些问题。首先,它具有 O(N) 复杂度。其次,我必须为每个 Enum 编写这样的代码。
  • @Max 不是针对每个枚举,而是针对那些具有引用变量并且需要通过引用值查找的枚举。关于 O(N),您可以对枚举中的所有值进行哈希映射并使用 get
  • 除非你的枚举有一百万个值,否则没关系。
【解决方案2】:

如何使用 Jackson 的面向方法的声明并使用输入字符串定义 setter,这将在内部实例化 enum ?

private SomeEnum someEnum;

public void setSomeEnum(String value ){}

【讨论】:

    猜你喜欢
    • 2015-10-19
    • 1970-01-01
    • 2021-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-16
    • 2020-07-17
    • 1970-01-01
    相关资源
    最近更新 更多