我正在开发一个以Web为主框架的Java webapp(Spring核心,Spring mvc,Spring安全,Spring数据,Spring websocket特别使用)。
在这样的Spring上下文中声明message-broker
为上下文提供了一个SimpMessagingTemplate
bean:
<websocket:message-broker>
<websocket:stomp-endpoint path="/stomp">
<websocket:sockjs/>
</websocket:stomp-endpoint>
<websocket:simple-broker prefix="/topic,/queue"/>
</websocket:message-broker>
我必须将此标记放在dispatcher-servlet.xml
(不是applicationContext.xml
)中,否则客户端在尝试连接到websocket时会获得404(在初始页面加载时)。
但是,由于提供SimpMessagingTemplate
bean(向连接的客户端发送消息)的此标记在根上下文中不可用,因此当服务(由根上下文扫描)发送websocket消息时,{ {1}} bean无法自动装配(经典SimpMessagingTemplate
)。
以前,NoSuchBeanDefinitionException
标记位于<websocket:message-broker>
且applicationContext.xml
正在导入dispatcher-servlet.xml
,一切正常 - 但我发现这是错误的我最近使用applicationContext.xml
来修改任意用户会话。
实际上,由于SessionRegistry
明确地导入了已经隐含继承的根上下文,因此DispatcherServlet
bean被创建了两次,导致意外行为(SO上有几个帖子描述了这一点)常见的错误,通常用户希望获得所有主体的列表,但由于SessionRegistry
bean重复而得到空列表,并找出相关信息。
为了解决这个问题,我删除了
SessionRegistry
来自dispatcher-servlet.xml的,但从那时起:
<import resource="applicationContext.xml"/>
标记放在dispatcher-servlet.xml中,在这种情况下,与websocket的连接成功但服务无法自动装配<websocket:messagebroker>...</>
SimpMessagingTemplate
标记放在<websocket:messagebroker>...</>
中,在这种情况下,客户端无法连接到websocket。 applicationContext.xml
导入DispatcherServlet
,这会打破ApplicationContext
- nope 这个可能是相当常见的问题的解决方案是什么? SessionRegistry
可以从根上下文访问bean,反之则不然,所以我应该如何解决这个问题呢?
答案 0 :(得分:0)
我找到了一个肮脏的解决方案。我不喜欢它,但由于缺乏SO的答案(另见:Dispatcher-servlet cannot map to websocket requests),以及现任和前任同事,我不得不继续进行项目并实施一个肮脏的修复。
脏修复是Autowire
控制器和预定类中的SimpMessagingTemplate
(全部由dispatcher-servlet
扫描,其中websocket tag
已声明),并通过SimpMessagingTemplate
作为服务方法的参数(在root context
中声明)。
此解决方案不透明(理想情况下SimpMessagingTemplate
应直接在服务中自动连接)但它肯定能解决问题。