spring4.2.5+websocket+sockjs+stomp关于@MessageMapping注解的Controller类的方法不起作用的问题
想要在站点里弄个站点内部通讯的小功能,遇到一个很神奇的问题:
加了注解的@MessageMapping的Controller类的方法如:
@MessageMapping("/send/{id}")
@SendTo("/topic/{id}")
public MessageEntity sendMesage(@Payload MessageEntity message){
return message;
}
但是前端使用 :
stompClient.send('/app/send/you',{},JSON.stringify({sender:'me',type:'E'}));
前端页面发送没异常,后台也没异常,就是请求不到 上述的Controller加了注解的方法上面。
上网搜索一圈是结果,发现有个国外站点的问题和我这个类似
链接:
其中有一个回答有点接近答案:
WebSocketConfig configuration class should be loaded as part of Servlet configuration, not Root configuration.
Make sure WebSocketConfig.class
returned from your implementation of AbstractAnnotationConfigDispatcherServletInitializer.getRootConfigClasses()
If you put it in root context, everything will work fine, you can use SimpMessagingTemplate, broker relay, but not @MessageMapping in controllers.
You can set breakpoint in WebSocketAnnotationMethodMessageHandler.initControllerAdviceCache()
and check what beanss are loaded in context. If no @Controller
marked bean in that method, @MessageMapping
will not work.
这段话的意思是:
WebSocketConfig 配置类应该被当做Servlet配置加载,而不是 Root配置。请确保WebSocketConfig.class 从你的AbstractAnnotationConfigDispatcherServletInitializer.getRootConfigClasses()实现中返回。
你可以在WebSocketAnnotationMethodMessageHandler.initControllerAdviceCache()方法
中设置断点查看上下文有哪些beans被加载,如果没有 @Controler标记的 bean 在方法里。@MessageMapping 将不会发挥作用。
但据我观察,我的这个类Controller是加载了的,而且其中的 一些action方法还可以执行。那问你可能就不是出在这个Controller没加载的问题。
难道是WebSocketConfig加载顺序有问题?我就按网上其他人的答案,重写 集成 AbstractAnnotationConfigDispatcherServletInitializer 这个类的方法。将WebSocketConfig.class 在 getServletConfigClasses 方法里返回。
然后测试后并没啥卵用。依旧是访问不到。
正在我要崩溃的时候,突然我想到了,加了注解@Controller类均被SpringMVC实例化加载的。他肯定不知道 @MessageMapping 注解是什么意思。而且这些消息通讯的动态接口要预先在WebSocket装配好才对呀。没装配的话,是不是WebSocketConfig在装配的时候,没有加载到这个Controller类,所以里面的加了注解 @MessageMapping的接口路径没有被注册上呢。
鬼使神差的在 WebSocketConfig配置类上加了 @CompanentScan(basePackageClasses="ChatController.class") 在上面:
启动后,发现问你居然解决了。啊哈哈哈...这太扯淡了。