Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson: Serialize and deserialize enum values as integers

Consider the following enum and class:

public enum State {
    OFF,
    ON,
    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:

{"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 0, which is the ordinal value of OFF in the enum State.

So the actual result I want to get is:

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

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

like image 513
SomethingSomething Avatar asked Jun 15 '16 11:06

SomethingSomething


People also ask

Can enum values be integers?

No, we can have only strings as elements in an enumeration.

How does Jackson deserialize enum?

Deserializing JSON String to Enum Using @JsonCreator Annotation. The @JsonCreator is another annotation that we can use for deserializing Enum. All the methods annotated by @JsonCreator are invoked by Jackson for getting an instance of the enclosing class.

How do you serialize an enum?

To serialize an enum constant, ObjectOutputStream writes the value returned by the enum constant's name method. To deserialize an enum constant, ObjectInputStream reads the constant name from the stream; the deserialized constant is then obtained by calling the java.

Can we change the numeric value of elements of enums?

Enum constants are implicitly static and final and you can not change their value once created.


3 Answers

It should work by specifying JsonValue mapper.

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

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

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

like image 193
user861594 Avatar answered Oct 03 '22 02:10

user861594


You can use setting

objectMapper.enable(SerializationFeature.WRITE_ENUMS_USING_INDEX); 

See https://github.com/FasterXML/jackson-databind/blob/master/src/test/java/com/fasterxml/jackson/databind/ser/TestEnumSerialization.java for complete test cases

Thanks to tip at https://righele.it/2016/01/30/jackson-deserialization-from-json-to-java-enums/

like image 27
Martin Avatar answered Oct 03 '22 02:10

Martin


You can use in this way

import com.fasterxml.jackson.annotation.JsonFormat;

@JsonFormat(shape = JsonFormat.Shape.NUMBER)
public enum State {
       OFF,
       ON,
       UNKNOWN
}
like image 27
dasunse Avatar answered Oct 03 '22 02:10

dasunse