Java Jackson:将枚举值序列化和反序列化为整数

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/37833557/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-11 19:43:16  来源:igfitidea点击:

Hymanson: Serialize and deserialize enum values as integers

javajsonserializationenumsHymanson

提问by SomethingSomething

Consider the following enum and class:

考虑以下枚举和类:

public enum State {
    ON,
    OFF,
    UNKNOWN
}

public class Machine {
    String name;
    int numCores;
    State state;

    public Machine(String name, int numCores, State state) {
        this.name = name;
        this.numCores = numCores;
        this.state = state;
    }
}

And consider the following main function:

并考虑以下主要功能:

public static void main(String args[]) {
    Machine m = new Machine("Machine 1", 8, State.OFF);
    ObjectMapper mapper = new ObjectMapper();
    String machineAsJsonString = mapper.writeValueAsString(m);
    System.out.println(machineAsJsonString);
}

Currently, the output of this main is:

目前,这个 main 的输出是:

{"name" : "Machine 1", "numCores" : 8, "state" : "OFF"}

This output is not good for me, as instead of the string "OFF"for state, I would like it to be 1, which is the ordinal value of OFFin the enum State.

这个输出对我来说并不好,因为我希望它不是字符串"OFF"for state,而是1,它是OFFenum 中的序数值State

So the actual result I want to get is:

所以我想得到的实际结果是:

{"name" : "Machine 1", "numCores" : 8, "state" : 1}

Is there some elegant way to make it behave this way?

有没有一些优雅的方式让它以这种方式表现?

采纳答案by user861594

It should work by specifying JsonValuemapper.

它应该通过指定JsonValue映射器来工作。

public enum State {
    ON,
    OFF,
    UNKNOWN;

    @JsonValue
    public int toValue() {
        return ordinal();
    }
}  

This works for deserialization also, as noted in Javadoc of @JsonValueannotation:

这也适用于反序列化,如注释的 Javadoc 中所述@JsonValue

NOTE: when use for Java enums, one additional feature is that value returned by annotated method is also considered to be the value to deserialize from, not just JSON String to serialize as. This is possible since set of Enum values is constant and it is possible to define mapping, but can not be done in general for POJO types; as such, this is not used for POJO deserialization

注意:当用于 Java 枚举时,一个附加功能是由带注释的方法返回的值也被认为是要反序列化的值,而不仅仅是要序列化的 JSON 字符串。这是可能的,因为 Enum 值集是常量,并且可以定义映射,但对于 POJO 类型通常不能这样做;因此,这不用于 POJO 反序列化

回答by Tom C

If you want to print the ordinal of the enum you can change your constructor to accept an intinstead of Stateand then in your call to Machineyou can structure it in the following way:

如果你想打印枚举的序号,你可以改变你的构造函数来接受一个int而不是,State然后在你的调用中Machine你可以按以下方式构造它:

Machine m = new Machine("Machine 1", 8, State.OFF.ordinal());

Machine m = new Machine("Machine 1", 8, State.OFF.ordinal());

This will get the enum ordinal value of the passed in state and print the following

这将获得传入状态的枚举序数值并打印以下内容

{name='Machine 1', numCores=8, state=1}

{name='Machine 1', numCores=8, state=1}

回答by Paco Abato

For completion I post another way: custom serializer:

为了完成,我发布了另一种方式:自定义序列化程序:

public class StateSerializer extends JsonSerializer<State> {  
    public void serialize(State value, JsonGenerator generator, SerializerProvider provider) throws IOException, JsonProcessingException {
        generator.writeStartObject();
        generator.writeFieldName("id");
        generator.writeNumber(value.getId());
        generator.writeEndObject();
    }
}

@JsonSerialize(using = StateSerializer.class)
public enum State { 
    ...
    public int getId(){...}
}

回答by Nikolai Shevchenko

Yet another way:

还有一种方式:

public enum State {

    @JsonProperty("0")
    ON,

    @JsonProperty("1")
    OFF,

    @JsonProperty("2")
    UNKNOWN
}

However, this will produce {"state" : "1"}instead of {"state" : 1}(string, not numeric). In most cases it's OK

但是,这将产生{"state" : "1"}而不是{"state" : 1}(字符串,而不是数字)。大多数情况下没问题

回答by dasunse

You can use in this way

你可以这样使用

import com.fasterxml.Hymanson.annotation.JsonFormat;

@JsonFormat(shape = JsonFormat.Shape.NUMBER)
public enum State {
       ON,
       OFF,
       UNKNOWN
}