用于接口的Kafka JSON反序列化程序



我遇到了类似的问题:Kafka反序列化嵌套泛型类型在我的卡夫卡生产商中,我发送的对象看起来像这样:

public class ExternalTO implements Serializable
{
private static final long serialVersionUID = 7949808917892350503L;
private List<IExternalData> externalDatas;
public ExternalTO()
{}
}

基石是:List<IExternalData> externalDatas

这个界面看起来像:

@JsonTypeInfo(use = JsonTypeInfo.Id.CLASS)
public interface IExternalData
{
String getOne();
}

在我的应用程序中,可以生成多种类型的IExternalBetData接口实现(大约10种不同)。例如,在这种情况下,我的生产者生成了带有ConcreteExternalData对象内部列表的ExternalTO。发送的JSON看起来像:

{
"externalDatas":
[{"@class":"com.api.external.to.ConcreteExternalData",
"one":false,
"two":false}]
}

添加字段@class是因为@JsonTypeInfo注释,我认为这足以让反序列化程序"理解"在反序列化中使用什么类型的IExternalData。不幸的是,在卡夫卡听众的一边,我得到了一个例外:

无法构造com.api.external.to.IExternalData的实例(否创建者,像默认构造一样,是存在的):抽象类型要么需要要映射到具体类型,请具有自定义反序列化程序,或包含附加类型信息

消费者看起来类似于:

@Service
public class Consumer
{
private final ObjectMapper objectMapper;

public Consumer(ObjectMapper objectMapper)
{
this.objectMapper = objectMapper;
}

@KafkaListener(topics = {"${kafka.topic}"})
public void listen(ConsumerRecord<String, String> record)
{
objectMapper.readValue(record.value(), ExternalTO.class)
}

请帮助解决这个问题。

IExternalData的所有实现中,反序列化器不知道它应该将消费者记录数据反序列化到哪个。我们必须解决这种歧义。我能够使用@JsonDeserialize注释来解决这个问题。

@JsonDeserialize(as=<实现>.class

清单声明之上

我的解决方案是将属性设置为objectMapper。

ObjectMapper mapper = new ObjectMapper();
// deserializes IExternalData into certain implementation.
mapper.enableDefaultTyping();

最新更新