Spring Kafka监听报错No method found for java.util.LinkedHashMap求解决
问题场景
现有如下Spring Boot Kafka监听器代码:
@Component @KafkaListener(topics = "mytopic") public class EventListener { @Jacksonized @Builder @Value @With @JsonIgnoreProperties(ignoreUnknown = true) @JsonInclude(JsonInclude.Include.NON_NULL) public static class Event { private final String id; } @KafkaHandler public void listen(Event event) { System.out.println("processing single event: " + event.toString()); } @KafkaHandler public void listenBatch(List<Event> events) { System.out.println("processing " + events.size() + " events"); } }
对应的配置类:
@Configuration public class ApplicationConfiguration { @Bean public RecordMessageConverter converter() { return new JsonMessageConverter(); } @Bean public BatchMessagingMessageConverter batchConverter() { return new BatchMessagingMessageConverter(converter()); } }
现象:向主题推送数组格式消息[{"id": "123"}]时,能正常触发listenBatch方法;但推送单条对象格式消息{"id": "123"}时,抛出异常:
org.springframework.kafka.listener.ListenerExecutionFailedException: Listener failed; nested exception is org.springframework.kafka.KafkaException: No method found for class java.util.LinkedHashMap
解决方案
方案一:在消息转换器中指定默认类型
修改配置类的converter()方法,为JsonMessageConverter配置类型映射器,指定默认反序列化类型为EventListener.Event:
@Configuration public class ApplicationConfiguration { @Bean public RecordMessageConverter converter() { JsonMessageConverter converter = new JsonMessageConverter(); DefaultJackson2JavaTypeMapper typeMapper = new DefaultJackson2JavaTypeMapper(); // 设置默认反序列化类型 typeMapper.setDefaultType(EventListener.Event.class); converter.setTypeMapper(typeMapper); return converter; } @Bean public BatchMessagingMessageConverter batchConverter() { return new BatchMessagingMessageConverter(converter()); } }
原理:通过指定默认类型,让JsonMessageConverter明确将单条JSON消息反序列化为Event实例,而非默认的LinkedHashMap,从而匹配listen(Event event)方法。
方案二:在@KafkaListener中指定payloadType
直接在监听器的@KafkaListener注解中添加payloadType属性,指定单条消息的目标类型:
@Component @KafkaListener(topics = "mytopic", payloadType = EventListener.Event.class) public class EventListener { // 内部类和方法保持不变 }
原理:该属性会告诉Spring Kafka将接收到的单条消息直接转换为指定的Event类型,无需额外配置消息转换器,实现更简洁。
异常原因说明
当发送单条JSON对象消息时,默认的JsonMessageConverter没有类型元数据(如消息头中的类型信息),会将JSON反序列化为LinkedHashMap;而你的监听器中仅定义了接收Event和List<Event>的@KafkaHandler方法,没有匹配LinkedHashMap的方法,因此抛出"找不到对应方法"的异常。批量消息则通过BatchMessagingMessageConverter结合配置的转换器,自动将数组元素转换为Event类型,所以能正常触发批量处理方法。
内容的提问来源于stack exchange,提问作者shj

