Spring WebSocket:如何仅为@SendTo注解应用@DestinationVariable?
解决Spring WebSocket中@DestinationVariable引发的参数绑定异常问题
你遇到的核心问题是对@DestinationVariable的作用范围理解有偏差——这个注解专门用于解析发送目标路径(比如@SendTo、@SendToUser)里的占位符,而非获取客户端发送消息的路径(@MessageMapping定义的路径)中的变量。
你的代码里,客户端是向/lock-document发送消息,这个路径里并没有{id}占位符,但你在方法参数上标注了@DestinationVariable("id"),Spring会尝试从客户端的消息路径里查找这个变量,自然会抛出参数绑定异常。
适配你需求的解决方案
根据你的逻辑(把消息中的documentId作为@SendTo路径的id),可以用SpEL表达式直接在@SendTo中引用方法参数的属性,完全不需要@DestinationVariable:
@Controller public class DocumentWebsocketController { @MessageMapping("/lock-document") // 用SpEL引用方法参数message的documentId属性填充占位符 @SendTo("/notify-open-documents/{#message.documentId}") public Response response(Message message) { return new Response(message.getDocumentId()); } }
补充场景说明
如果后续业务需要从客户端发送的路径中获取id(比如客户端发送到/lock-document/123),可以修改@MessageMapping的路径,同时用@DestinationVariable获取这个参数,此时@SendTo里的{id}会自动绑定该参数值:
@Controller public class DocumentWebsocketController { // 修改@MessageMapping为带占位符的路径 @MessageMapping("/lock-document/{id}") @SendTo("/notify-open-documents/{id}") // 这里的@DestinationVariable用来获取客户端发送路径中的id public Response response(@DestinationVariable("id") Long id, Message message) { return new Response(id); } }
但根据你的描述,客户端的消息路径里没有id,所以第一种用SpEL的方案更适配当前场景。
内容的提问来源于stack exchange,提问作者pidabrow
相关产品推荐
相关产品推荐

