在Kafka JSON序列化中将超类型作为类型信息发送

时间:2019-04-19 08:00:53

标签: java spring spring-boot apache-kafka spring-kafka

我正在使用Spring Boot使用Kafka将数据从一个应用程序发送到另一个应用程序。

我的设计使用接口声明要发送的数据:

package domain;

interface Data {
    public String getData();
    public void setData(String data);
}

制作人

在源应用程序中,我将此接口实现为db Entity。

package persistence;

@Data
class DataEntity implements Data {
    private String data;  // lombok generates getter/setters
}

添加实体后,我想使用KafkaTemplate将其作为更新发送给Kafka

@Component
class DataPublisher implements ApplicationListener<DataEvent> {
    @Autowired private KafkaTemplate<String,Data> template;

    // I left out DataEvent which is a straightforward ApplicationEvent override
    @EventListener(classes = DataEvent.class)
    public void onApplicationEvent(DataEvent event) {
        template.send("data", (Data) event.getSource());
    }
}
// triggered by this call in a service
    eventPublisher.publishEvent(new DataEvent(updatedData));

序列化是通过属性完成的

spring:
    kafka:
        consumer:
            value-deserializer: org.springframework.kafka.support.serializer.JsonDeserializer
            properties.spring.json.value.default.type: domain.Data

查看kafkacat的输出,数据发送正常。

消费者

在接收方,我有

@KafkaListener(topics = "data")
public void dataUpdated(@Payload Data data) {
    dataService.updateData(data);
}

结果

  

原因:java.lang.IllegalArgumentException:类'persistence.DataEntity'不在受信任的程序包中[...]

我很好理解-序列化程序发送一个persistence.DataEntity对象,但是客户端期望一个domain.Data对象。但这就是设计的本意。我希望客户端仅了解域包,而不是其persistence实现。 (作为附带的问题,我在哪里可以看到此类型的标头?它不在编码的json AFAICT中,我缺少什么?)

所以问题是:如何强制Spring JsonDeserializer发送domain.Data作为序列化数据类型?

我在序列化程序类中确实找到了TYPE_MAPPING属性,但是它唯一的文档是它“将类型映射添加到类型映射器:'foo:com.Foo,bar:com.Bar'”,而没有”什么都没解释,我找不到示例用法。

编辑:

我确实添加了

  

spring.kafka.producer.properties.spring.json.type.mapping = domain.Data:persistence.DataEntity

到生产者的属性,但这没有帮助。

1 个答案:

答案 0 :(得分:1)

请参见the documentation

您必须在两侧都提供映射。

但是,您应该使用JsonDeserializerBytesDeserializer(只需将其中一个添加为BytesJsonMessageConverter,而不是使用@Bean,Boot会将其连接到容器中工厂)。

那样,框架将自动转换为参数类型。

再次,请参见the documentation