gpt4 book ai didi

java - Jackson中的多态反序列化没有注释

转载 作者:行者123 更新时间:2023-12-01 14:17:32 27 4
gpt4 key购买 nike

我有一个 CloudEvent<T>使用 Jackson(2.9.0 - 最新版本)进行多态反序列化的类,如下所示:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class CloudEvent<T> {

@NonNull
private String eventType;

@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
property = "eventType",
defaultImpl = Void.class)
@JsonSubTypes({
@JsonSubTypes.Type(value = MyEvent1.class, name = "event-1"),
@JsonSubTypes.Type(value = MyEvent2.class, name = "event-2")
})
private T data;
}

然后反序列化:
String cloudEventJson1 = "{\"eventType\":\"event-1\",\"data\":{\"id\":\"123\",\"details\":\"detail1\"}}";

CloudEvent deserializedEvent1 = objectMapper.readValue(cloudEventJson1, CloudEvent.class); //without subtypes

这一切都很好。
但是因为一些限制,我不能在 CloudEvent 类上使用注解(由外部依赖提供)。

所以我像这样配置了 ObjectMapper:
    ObjectMapper objectMapper = new ObjectMapper();
objectMapper.registerSubtypes(new NamedType(MyEvent1.class, "event-1"));
objectMapper.registerSubtypes(new NamedType(MyEvent2.class, "event-2"));

TypeResolverBuilder typeResolverBuilder = new ObjectMapper.DefaultTypeResolverBuilder(ObjectMapper.DefaultTyping.OBJECT_AND_NON_CONCRETE)
.init(JsonTypeInfo.Id.NAME, null) //CLASS works
.inclusion(JsonTypeInfo.As.EXTERNAL_PROPERTY)
.typeProperty("eventType")
.typeIdVisibility(true)
// .defaultImpl(Void.class);
objectMapper.setDefaultTyping(typeResolverBuilder);

但是使用与上述相同的方法进行反序列化不起作用。它正在阅读 eventType但它无法与注册的子类型匹配。
我不能在反序列化中使用泛型或 TypeReference,因为我需要使用 spring-integration用于阅读只接受主类的事件;反序列化后手动完成模式匹配。

异常(exception):
com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Could not resolve type id 'event-1' as a subtype of [simple type, class java.lang.Object]: known type ids = [] (for POJO property 'data')
at [Source: (String)"{"eventType":"event-1","data":{"id":"123","details":"detail1"}}"; line: 1, column: 271]

这也是为所有输入类配置 ObjectMapper。可以连接这个 typeResolverBuildersubtypesCloudEvent.class (就像注释方式一样)。

最佳答案

即使你不能修改你的类,你仍然可以依赖注解。 Jackson 支持一种称为 mix-ins 的功能:您可以将其视为一种在运行时添加更多注释的面向方面的方式,以增加静态定义的注释。

首先定义一个接口(interface)如下:

public interface CloudEventMixIn<T> {

@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.EXTERNAL_PROPERTY,
property = "eventType",
defaultImpl = Void.class)
@JsonSubTypes({
@JsonSubTypes.Type(value = MyEvent1.class, name = "event-1"),
@JsonSubTypes.Type(value = MyEvent2.class, name = "event-2")
})
public T getData();
}

然后配置 ObjectMapper使用定义的接口(interface)作为实际类/接口(interface)的混合:

ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(CloudEvent.class, CloudEventMixIn.class);

来自 addMixIn(Class<?> target, Class<?> mixinSource) 方法文档:

Method to use for adding mix-in annotations to use for augmenting specified class or interface. All annotations from mixinSource are taken to override annotations that target (or its supertypes) has.

关于java - Jackson中的多态反序列化没有注释,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55243350/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com