jackson-databind icon indicating copy to clipboard operation
jackson-databind copied to clipboard

Feature request: Enum (de)serialization in conjunction with JsonFormat.Shape.NUMBER_INT

Open kistlers opened this issue 1 year ago • 2 comments

Is your feature request related to a problem? Please describe. Not a problem, as there is a relatively clear and simple way to achieve the same, albeit slightly more limited, functionality. See below:

Describe the solution you'd like I would like to see the functionality of the @JsonProperty annotation on enum values be extended to output the value as integers (and potentially other types) in the JSON output (and also deserialized with the same logic). I imagine a @JsonFormat(shape = JsonFormat.Shape.NUMBER_INT) annotation on the property in the POJO would define the output format of the enum value given to @JsonProperty as a string. Hence, see the example below.

Usage example

The following example is taken from StackOverflow, an answer by user SomethingSomething:

public enum State {

    @JsonProperty("0")
    OFF,

    @JsonProperty("1")
    ON,

    @JsonProperty("2")
    UNKNOWN
}

The enum State in the following POJO would be serialized as {"state": "1"}, all good so far.

public record Pojo {
    @JsonProperty("state") State state
}

However, consider the following case:

public record Pojo(
    @JsonFormat(shape = JsonFormat.Shape.NUMBER_INT) @JsonProperty("state") State state
) {}

I would like to see this case result in JSON such as {"state": 1}, with the value being a number (int in that case) instead of a string.

Additional context

I know I can achieve the same functionality using @JsonValue and @JsonCreator annotations:

public enum State {

    OFF(0),

    ON(1),

    UNKNOWN(2);

    private final int value;

    State(final int value) {
        this.value = value;
    }
    
    @JsonValue
    public int getValue() {
        return value;
    }
    
    @JsonCreator
    public State forValue(final int value) {
        return Arrays.stream(values())
                .filter(v -> v.value == value)
                .findFirst()
                .orElseThrow();
    }
}

The proposed feature would allow us to shortcut these methods. Before Jackson supported the @JsonProperty annotation on enum values, the above was also the way to (de)serialize enums to other strings, this feature would extend the functionality of the @JsonProperty annotation to integers and potentially other types.

I originally posted this idea in the Ideas section of the main Jackson repo, where cowtowncoder suggested filing a feature request here.

I would like to see something like that be supported in some way or form.

kistlers avatar Aug 23 '22 06:08 kistlers

so basically the combination of @JsonProperty and @JsonFormat on enum should let the property value be coerced to the type specified by the format?

yawkat avatar Aug 23 '22 08:08 yawkat

Yes, @yawkat, this is would be my first idea that would use existing annotations. I could also imagine some other annotation or argument to @JsonProperty that allows arguments of type other than String.

kistlers avatar Aug 23 '22 10:08 kistlers