Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Jackson cannot convert empty string value to enum

I am looking for a handy solution with Jackson (2.8) to filter out fields pointing to empty String value before/during deserialization:

@JsonInclude(JsonInclude.Include.NON_EMPTY)
public class Guis {

public enum Context {
    SDS,
    NAVIGATION
}

public enum Layer {
    Library,
    Status,
    Drivingdata
}

// client code

 String s = "{\"context\":\"\",\"layer\":\"Drivingdata\"}";
 ObjectMapper mapper = new ObjectMapper();
 Guis o = mapper.readValue(s, Guis.class);

Error

 Exception in thread "main" com.fasterxml.jackson.databind.exc.InvalidFormatException: Can not deserialize value of type cq.speech.rsi.api.Guis$Context from String "": value not one of declared Enum instance names: [SDS NAVIGATION] at [Source: {"context":"","layer":"Drivingdata"}; line: 1, column: 12] (through reference chain: cq.speech.rsi.api.Guis["context"])

What else I tried... Ah this one

mapper.getDeserializationConfig().with(DeserializationFeature.ACCEPT_EMPTY_STRING_AS_NULL_OBJECT);

The error remains and apparently even googling around didn't help much...

EDIT

set DeserializationFeature does not work as exemplified above. For me the solution was eventually to add this snippet:

 mapper.configure(DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL, true)
like image 692
crishushu Avatar asked Jul 18 '18 16:07

crishushu


2 Answers

You can enable DeserializationFeature.READ_UNKNOWN_ENUM_VALUES_AS_NULL for your mapper, its disabled by default. Only caveat to using this, it will treat all unknown including empty string as null for enum.

like image 90
Amith Kumar Avatar answered Sep 20 '22 17:09

Amith Kumar


You can use a factory that returns a null value if the string doesn't match an enum literal:

public enum Context {
    SDS,
    NAVIGATION;

    @JsonCreator
    public static Context forName(String name) {
        for(Context c: values()) {
            if(c.name().equals(name)) { //change accordingly
                return c;
            }
        }

        return null;
    }
}

Of course the implementation can change according to your logic, but this allows the use of null values for the enum.

The JsonCreator annotation tells Jackson to call the method to get an instance for the string.

like image 36
ernest_k Avatar answered Sep 21 '22 17:09

ernest_k