Jackson - 将接口反序列化为枚举

Cli*_*ote 7 java json jackson

我有一个接口Event和多个枚举实现此接口(UserEventBusinessEvent,等)。

我想反序列化以下 json 数据:

{
  "event" : "SIGNUP"
}
Run Code Online (Sandbox Code Playgroud)

给这个豆子:

public class Input
{ 
   private Event event;

   public Event getEvent() {..}
   public void setEvent(Event event) {..}
}

public enum UserEvent implements Event
{
    SIGNUP;
}
Run Code Online (Sandbox Code Playgroud)

在这里,我希望将事件反序列化为UserEvent.SIGNUP.

我怎样才能做到这一点?继续阅读@JsonTypeInfo似乎表明需要一个额外的type属性,但在这种情况下,只有一个字符串直接映射到枚举值。

Vla*_*nin 4

您正在使用Event字段输入接口event,而杰克逊对此接口的实现Input一无所知。UserEvent

您可以使用自定义JsonDeserializer来获取值:

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));
}
Run Code Online (Sandbox Code Playgroud)

  • 这个解决方案是否会让您陷入只能对“Event”字段使用单个具体实现的困境?由于您使用 UserEventDeserializer 注释了 Event 字段的 getter,如果 Event 字段中的具体值是 BusinessEvent 会发生什么? (2认同)