I am sending `List<Object>` from Kafka Producer to a topic. A consumer which listens to the topic receives the message but in a different format(i.e. `List<LinkedHashMap>` instead of `List<Object>`)
Any idea on how to receive the List<Object> messages in the consumer?I am sending `List<foo>`. But in the Consumer, data comes as `List<LinkedHashMap>`
只需更改以下示例作为列表 https://memorynotfound.com/spring-kafka-json-serializer-deserializer-example/ 从链接中可以找到发件人和侦听器。唯一的变化是发件人将使用对象而不是Foo。
public class SpringKafkaApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(SpringKafkaApplication.class, args);
}
@Autowired
private FooSender sender;
@Override
public void run(String... strings) throws Exception {
List<Foo> f = new ArrayList<>();
f.add(new Foo("Spring Kafka", "sending and receiving JSON messages"))
f.add(new Foo("Spring Kafka1", "sending and receiving11"))
sender.send(f);
}
}
答案 0 :(得分:1)
不要在注释中添加代码;很难阅读-而是编辑问题。
您使用的是什么版本的spring-kafka?
您至少需要2.1.x和一个Kafka代理> = 0.11,以便可以在标头中传达类型信息。 See here。
在早期版本中,必须将解串器配置为目标类型。
编辑
我看到了问题;由于类型擦除,序列化程序不知道容器(列表)的内容类型,因此它不会尝试对集合进行内部检查以找到类型。
虽然我们可以针对集合之类的简单情况解决此问题,但更复杂的对象(例如地图)将是一个挑战。
数组而不是列表可能会起作用。
同时,您可以改用消息转换器,在此我们使用侦听器的参数类型来确定所需的类型。这是一个示例:
@SpringBootApplication
public class So53665459Application2 {
public static void main(String[] args) {
SpringApplication.run(So53665459Application2.class, args);
}
@Bean
public NewTopic topic() {
return new NewTopic("so53665459", 1, (short) 1);
}
@Bean
public MessageConverter converter() {
return new StringJsonMessageConverter();
}
@KafkaListener(id = "so53665459", topics = "so53665459")
public void listen(List<Foo1> foos) {
System.out.println(foos);
}
@Bean
public ApplicationRunner runner(KafkaTemplate<String, List<Object>> template) {
return args -> template.send("so53665459", Collections.singletonList(new Foo1("baz1")));
}
public static class Foo1 {
private String bar;
public Foo1() {
super();
}
Foo1(String bar) {
this.bar = bar;
}
public String getBar() {
return this.bar;
}
public void setBar(String bar) {
this.bar = bar;
}
@Override
public String toString() {
return "Foo1 [bar=" + this.bar + "]";
}
}
}
和
spring.kafka.producer.value-serializer=org.springframework.kafka.support.serializer.JsonSerializer
#spring.kafka.consumer.value-deserializer= boot's default StringDeserializer
spring.kafka.consumer.enable-auto-commit=false
spring.kafka.consumer.auto-offset-reset=earliest
和
[Foo1 [bar=baz1]]
或者,您可以对序列化器进行子类化,以使用适当的类型设置标头,以帮助反序列化器。