Q: How retrieve Class that annotated by Jackson @JsonDeserialize? My task is deserialize json object to enum. See example at the end of the page.
But I can't define which enum create in method JsonEnumDeserializer.deserialize (Drive or some other).
I want just annotate my enum @JsonDeserialize(using = JsonEnumDeserializer.class) and it should deserialize all annotated enum by way I described.
1) For this I tried extend org.codehaus.jackson.map.deser.std.EnumDeserializer but it fails at runtime requiring no arg constructor or fails at compile time requiring override just parent constructor EnumDeserializer(EnumResolver<?> res).
I tried dig into EnumDeserializer how it retrieve Enum Class but it did not give me any result.
2) Other solution add field "type" to json, but it's bad solution.
In method JsonEnumDeserializer.deserialize I would like retrieve Class that annotated by @JsonDeserialize (it will solve problem). Could somebody help me?
{
  "make":"Mazda",
  "model":"6",
  "drive":{
    "id":"FWD",
    "name":"Front wheel drive"
  }
}

public class Car {
    private String make;
    private String model;
    private Drive drive;

    /* setters and getters */
}

@JsonDeserialize(using = JsonEnumDeserializer.class)
public enum Drive {
    FWD, RWD, AWD
}

public class JsonEnumDeserializer extends JsonDeserializer<Enum> {
    @Override
    public Enum deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        String enumName = jp.readValueAsTree().findValue("id").asText();
        return ??? /* Knowing enumName how can I figure out which enum Class return? Drive enum or other enum? I want write universal deserializer for all enum */
    }
}


A: One solution I found is change Jackson to Gson. Gson can say instance of which Class is expected to be returned. Argument Type type.
public class GsonEnumDeserializer implements JsonDeserializer<Enum> {
    @Override
    public Enum deserialize(JsonElement jsonElement, Type type, JsonDeserializationContext jsonDeserializationContext) throws JsonParseException {
        try {
            Class enumClass = Class.forName(type.getTypeName());
            String enumName = jsonElement.getAsJsonObject().get("id").getAsString();
            return (Enum) enumClass.getMethod("valueOf", String.class).invoke(null, enumName);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
}

/* usage */
Gson gson = new GsonBuilder()
    .registerTypeHierarchyAdapter(Enum.class, new GsonEnumDeserializer())
    .create();
Car car = gson.fromJson(carJson, Car.class);


A: You don't need a custom JsonDeserializer at all in this case.
The drive field in Car is an enum, not an Object, so your json should be:
{
  "make":"Mazda",
  "model":"6",
  "drive":"FWD"
}

Either your json text or you're Car class is wrong.
