Niraj Sonawane
Niraj Sonawane

Reputation: 11115

Enum deserialization using @JsonValue does not works for int values. It is using Index value instead of actual value

Enum conversion done using @JsonValue is not working for int values in jackson. During conversion it is using enum index value instead of actual value. @JsonValue attribute is working for String enums

I am using Spring Boot 2.2.2.RELEASE

Controller

@PostMapping("/test")
    public ResponseEntity enumTest(@RequestBody Request request ){
        log.info(request.toString());
        return ResponseEntity.status(HttpStatus.OK).build();
    }  

Request Object

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Request {
    private IntEnum intEnum;
    private  StringEnum stringEnum;
}

String Enum //@jsonValue is working for StringEnum Class

public enum  StringEnum {

    FIRST("first"),SECOND("second");
    @JsonValue
    private final String stringValue;
        StringEnum(String second) {
        this.stringValue=second;
    }
}

Int Enum

public enum IntEnum {
    ONE(1), TEN(10);    
    @JsonValue
    private final int intValue;    
    IntEnum(int i) {
        this.intValue = i;    
    }
}

@jsonValue is not working for intEnum Class,

If i pass 1 in request it correctly converts to enum value ONE BUT but if i pass 10 in request it say

index value outside legal index range [0..1]; nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `com.example.demo.IntEnum` from number 10: index value outside legal index range [0..1]\n at [Source: (PushbackInputStream); line: 2, column: 15] (through reference chain: com.example.demo.Request[\"intEnum\"])",

json request

{
    "intEnum":10,
    "stringEnum":"first" 
 }

Upvotes: 3

Views: 3848

Answers (1)

Niraj Sonawane
Niraj Sonawane

Reputation: 11115

I Was able to get it working using @JsonCreator
For @JsonValue with integer We need to explicitly add JsonCreator

public enum IntEnum {
    ONE(1), TEN(10);

    @JsonValue
    private final int intValue;

    IntEnum(int i) {
        this.intValue = i;
    }

    @JsonCreator
    public static IntEnum fromNumber(int number) {
        for (IntEnum b : IntEnum.values()) {
            if (b.intValue == number) {
                return b;
            }
        }
        return null;
    }

}

Upvotes: 2

Related Questions