I have an interface Event
and multiple enums that implement this interface (UserEvent
, BusinessEvent
, etc).
I want to deserialize the following json data:
{
"event" : "SIGNUP"
}
To this bean:
public class Input
{
private Event event;
public Event getEvent() {..}
public void setEvent(Event event) {..}
}
public enum UserEvent implements Event
{
SIGNUP;
}
Here, i'd like event to be deserialized to UserEvent.SIGNUP
.
How can I accomplish this? Reading up on @JsonTypeInfo
seems to indicate that an additional type
attribute would be needed, but in this case, there's just one string which maps directly to an enum value.
By default, Jackson will use the Enum name to deserialize from JSON. If we want Jackson to case-insensitively deserialize from JSON by the Enum name, we need to customize the ObjectMapper to enable the ACCEPT_CASE_INSENSITIVE_ENUMS feature.
Yes, Enum implements an interface in Java, it can be useful when we need to implement some business logic that is tightly coupled with a discriminatory property of a given object or class. An Enum is a special datatype which is added in Java 1.5 version.
It's perfectly legal to have an enum declared inside an interface . In your situation the interface is just used as a namespace for the enum and nothing more. The interface is used normally wherever you use it.
Because enums are automatically Serializable (see Javadoc API documentation for Enum), there is no need to explicitly add the "implements Serializable" clause following the enum declaration. Once this is removed, the import statement for the java. io. Serializable interface can also be removed.
You are using Event
interface for field event
in Input
and jackson doesn't know anything about UserEvent
as implementation of this interface.
You can use custom JsonDeserializer
to get value:
public interface Event {
}
public static class Input
{
private Event event;
@JsonDeserialize(using = EventDeserializer.class)
public Event getEvent() {
return event;
}
public void setEvent(Event event) {
this.event = event;
}
}
public enum UserEvent implements Event
{
SIGNUP;
}
public static class EventDeserializer extends StdDeserializer<Event> {
protected EventDeserializer() {
super(Event.class);
}
@Override
public Event deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
return UserEvent.valueOf(p.getText());
}
}
@Test
public void converEnum() throws Exception {
ObjectMapper objectMapper = new ObjectMapper();
Input input = objectMapper.readValue("{\n" +
" \"event\" : \"SIGNUP\"\n" +
"}", Input.class);
Assert.assertThat(input.getEvent(), Matchers.is(UserEvent.SIGNUP));
}
For a single enum the jsonschema2pojo-maven-plugin generates code like the following:
@JsonCreator
public static Foo fromValue(String value) {
Foo constant = CONSTANTS.get(value);
if (constant == null) {
throw new IllegalArgumentException(value);
} else {
return constant;
}
}
I guess you could write a factory method which is annotated with @JsonCreator and somehow decides which enum to choose. I'm not sure if it matters much where you put this method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With