Kotlin Spring Boot WebSocket协程接口报错:无法构造Continuation实例
问题分析与解决
问题原因
Spring MVC(REST接口)对Kotlin协程suspend函数有专门的适配逻辑:它会自动识别并处理suspend函数隐式添加的Continuation参数,不会将其交给消息转换器解析。但Spring Messaging(WebSocket依赖的模块)在处理@MessageMapping注解的suspend函数时,早期版本的适配不完善,错误地将Continuation参数当作需要从请求JSON中解析的字段,而kotlin.coroutines.Continuation是协程内部类,没有无参构造函数,因此触发MessageConversionException。
解决方案
方案1:将WebSocket接口改为非挂起函数,内部调用协程
修改WebSocket控制器代码,把suspend函数改为普通函数,通过runBlocking调用协程逻辑(保证同步返回结果以适配@SendTo):
@Controller class WebSocketController(private val processFacade: ProcessFacade) { private val logger = KotlinLogging.logger {} @MessageMapping("/ws") @SendTo("/topic/test") fun processOperation(@RequestBody processRequest: ProcessRequest): ProcessResponse { return runBlocking { processFacade.processOperation(processRequest) } } }
方案2:升级Spring Boot版本
如果项目使用的是Spring Boot 2.x,建议升级到Spring Boot 3.x版本。Spring Boot 3.x对Kotlin协程的支持更完善,包括Spring Messaging模块对suspend函数的适配,能自动处理Continuation参数,无需修改代码即可解决问题。
方案3:手动配置消息转换器(可选)
确保Jackson Kotlin模块被正确注册到Spring Messaging的消息转换器中,不过此方案优先级低于前两者,因为核心问题是协程参数的识别而非Jackson配置:
@Configuration class WebSocketConfig : WebSocketMessageBrokerConfigurer { override fun configureMessageConverters(converters: MutableList<MessageConverter>) { val jacksonConverter = MappingJackson2MessageConverter() jacksonConverter.objectMapper = ObjectMapper().registerModule(KotlinModule()) converters.add(jacksonConverter) } }
内容的提问来源于stack exchange,提问作者salerokada
相关产品推荐
相关产品推荐

