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

考虑以下枚举和类:

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; } } 

并考虑以下主要function:

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

目前,这个主要的输出是:

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

这个输出对我来说不好,因为代替state字符串"OFF" ,我希望它是1 ,这是枚举StateOFF的序数值。

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

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

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

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

 public enum State { ON, OFF, UNKNOWN; @JsonValue public int toValue() { return ordinal(); } } 

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

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

你可以使用设置

 objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_INDEX); 

有关完整的测试用例,请参阅https://github.com/FasterXML/jackson-databind/blob/master/src/test/java/com/fasterxml/jackson/databind/ser/TestEnumSerialization.java

感谢https://righele.it/2016/01/30/jackson-deserialization-from-json-to-java-enums/

如果要打印枚举的序号,可以将构造函数更改为接受int而不是State ,然后在对Machine的调用中,可以按以下方式构造它:

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

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

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

完成后我发布另一种方式:自定义序列化器:

 public class StateSerializer extends JsonSerializer { 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(){...} } 

另一种方式:

 public enum State { @JsonProperty("0") ON, @JsonProperty("1") OFF, @JsonProperty("2") UNKNOWN } 

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