Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson - Serialize / Deserialize Enums with Integer fields

There is a very similar question here - Jackson: Serialize and deserialize enum values as integers which deals with using Jackson to serialize and deserialize enums whose solution is pretty simple by using @JsonValue annotation.

This does not work in case we have an enum with an integer field like below.

enum State{
    GOOD(1), BAD(-1), UGLY(0);

    int id;

    State(int id) {
        this.id = id;
    }
}

And if our requirement is to serialize and provide the actual value instead of name(). Say, something like {"name":"foo","state":1} representing GOOD for foo. Adding @JsonValue annotation can help only in case of serialization and fails for deserialization. If we do not have fields, meaning that GOOD=0, BAD=1, UGLY=2, @JsonValue would be sufficient and Jackson fails to deserialize when fields exist - wrong mapping for 0 and 1 and exception for -1.

like image 358
Pavan Kumar Avatar asked Feb 21 '18 08:02

Pavan Kumar


2 Answers

This can be achieved using Jackson annotation @JsonCreator. For serialization, a method with @JsonValue can return an int and for deserialization, a static method with @JsonCreator can accept an int in parameter as provided below.

Code below for reference:

enum State{
    GOOD(1), BAD(-1), UGLY(0);

    int id;

    State(int id) {
        this.id = id;
    }

    @JsonValue
    int getId() {
        return id;
    }

    @JsonCreator
    static State fromId(int id){
        return Stream.of(State.values()).filter(state -> state.id == id).findFirst().get();
    }

}

Note: This is currently an open bug on Jackson library - https://github.com/FasterXML/jackson-databind/issues/1850

like image 126
Pavan Kumar Avatar answered Nov 15 '22 00:11

Pavan Kumar


I had problems with the other solutions. This worked for me (Jackson 2.9.9):

@JsonFormat(shape = JsonFormat.Shape.OBJECT)
enum State{
    GOOD(1), BAD(-1), UGLY(0);

    int id;

    State(int id) {
        this.id = id;
    }

    @JsonValue
    int getId() { return id; }
}
like image 43
Matteo Cossu Avatar answered Nov 15 '22 00:11

Matteo Cossu