Java Jackson 反序列化实现了接口的抽象类的子类

huangapple go评论79阅读模式
英文:

Java Jackson deserialize abstract class child which implements interface

问题

我有一个接口:

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = ChildA.class, name = "childA"),
        @JsonSubTypes.Type(value = ChildB.class, name = "childB"),
})
public interface Event {
}

然后是实现该接口的抽象类:

public abstract class SpecificEvent implements Event {
    private ZonedDateTime timestamp;
}

最后是抽象类的子类:

public class ChildA extends SpecificEvent {
}

public class ChildB extends SpecificEvent {
}

Jackson 在反序列化子类时出现错误:

无法将类型标识 'childA' 解析为 packages.SpecificEvent 的子类型。

我做错了什么?

更新:

我正在通过 RabbitMQ 消费子类的消息。
Rabbit 配置:

public ObjectMapper objectMapper() {
    var mapper = new ObjectMapper();
    mapper.registerModule(new JavaTimeModule());
    mapper.registerModule(new Jdk8Module());
    mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
    mapper.setDateFormat(StdDateFormat.instance
            .withTimeZone(TimeZone.getTimeZone(ZoneId.of("Europe/Moscow")))
            .withLocale(new Locale("ru"))
    );
    mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
    return mapper;
}

public MessageConverter jsonMessageConverter() {
    return new Jackson2JsonMessageConverter(objectMapper());
}

发送事件只需使用 RabbitTemplate:

rabbitTemplate.convertAndSend(
        exchange.getName(),
        event.getEventRouteKey().getKey(),
        event
);

通过 @RabbitListener 监听消息。

英文:

I have an interface:

@JsonTypeInfo(
        use = JsonTypeInfo.Id.NAME,
        property = "type")
@JsonSubTypes({
        @JsonSubTypes.Type(value = ChildA.class, name = "childA"),
        @JsonSubTypes.Type(value = ChildB.class, name = "childB"),
})
public interface Event {
}

And then abstract class which implements this interface:

public abstract class SpecificEvent implements Event {
    private ZonedDateTime timestamp;
}

And finally children of abstract class:

public class ChildA extends SpecificEvent {
}

public class ChildB extends SpecificEvent {
}

Jackson fails to deserialize children with error:

> Could not resolve type id 'childA' as a subtype of
> packages.SpecificEvent.

What am i doing wrong?

UPD

I'm consuming messages of children throw RabbitMQ.
Rabbit config:

   public ObjectMapper objectMapper() {
        var mapper = new ObjectMapper();
        mapper.registerModule(new JavaTimeModule());
        mapper.registerModule(new Jdk8Module());
        mapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, true);
        mapper.setDateFormat(StdDateFormat.instance
                .withTimeZone(TimeZone.getTimeZone(ZoneId.of("Europe/Moscow")))
                .withLocale(new Locale("ru"))
        );
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper;
    }

    public MessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter(objectMapper());
    }

For sending events i just use RabbitTemplate:

    rabbitTemplate.convertAndSend(
            exchange.getName(),
            event.getEventRouteKey().getKey(),
            event
    );

And listen to it via @RabbitListener.

答案1

得分: 0

实际上,在更改模型之前,我忘记在Rabbit中清除队列,这就是为什么我收到了反序列化错误。

英文:

Actually, i forgot to purge queue in Rabbit, before changing the models, that's why i got deserialization error.

huangapple
  • 本文由 发表于 2020年9月29日 23:45:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/64123084.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定