spring-mvc – 如何在Spring WebSocket处理程序中访问“会话”范围的bean(不是“websocket”范围)

在原始的
Spring WebSocket应用程序中(不使用sockjs / STOMP或任何其他中间件),如何在HTTP会话范围内注册Spring注入bean,以便它们可以被我的WebSocketHandler bean中的代码使用?

请注意,我不会问的是以下任何一个问题:

>如何在同一WebSocket会话的所有处理程序调用都可访问的作用域中创建bean(例如,如Request or Session scope in Spring Websocket的答案中所述).我需要访问的bean已经存在于HTTP会话的范围内
>我如何(以编程方式)访问servlet容器的HTTP会话存储中的对象(我没有尝试过这样做,但我很确定答案涉及使用HttpSessionHandshakeInterceptor),但这并没有让我注入Spring范围依赖.
>如何使用ScopedProxy在不同范围的代码之间传递bean(例如,如here所述);我已经熟悉如何执行此操作,但尝试对WebSocketHandler执行此操作会导致错误,因为会话范围尚未在访问对象时绑定到线程.
> How to access the current security principal – 再次,非常有用,但不是我目前正在努力实现的目标.

我希望做的是提供一个简单的框架,允许MVC应用程序的传统HTTP请求启动部分直接与WebSocket协议通信(用于向客户端发送简单的推送更新).我希望能够做的是将数据从MVC控制器推送到会话范围对象,并将其从websocket处理程序中拉出来.我希望从MVC控制器的角度来看这个最简单的API,如果可以只使用会话范围的bean,那将是理想的.如果您对分享这些数据的非常简单的方法有任何其他想法,我也想听听这些方法无法实现的情况.

最佳答案 您还可以将Java API用于websocket.这个链接
https://spring.io/blog/2013/05/23/spring-framework-4-0-m1-websocket-support

解释了如何使用Spring执行此操作.

不幸的是,这样的事情

@ServerEndpoint(value = "/sample", configurator = SpringConfigurator.class)
public class SampleEndpoint {

     private SessionScopedBean sessionScopedBean;

     @Autowired
      public SampleEndpoint(SessionScopedBean sessionScopedBean) {
        this.sessionScopedBean = sessionScopedBean;
      }
}

导致异常(因为我们试图访问其范围之外的bean),但对于单例和原型bean,它运行良好.

要使用会话属性,您可以修改hanshake并传递所需的属性:

public class CustomWebSocketConfigurator extends SpringConfigurator {
    @Override
    public void modifyHandshake(ServerEndpointConfig config,
            HandshakeRequest request,
            HandshakeResponse response) {

        //put attributes from http session to websocket session
        HttpSession httpSession = (HttpSession) request.getHttpSession();
        config.getUserProperties().put("some_attribute",
               httpSession.getAttribute("some_attribute_in_http_session"));
    }
}

P. S.更多评论而不是答案.我只想添加另一种方法来处理websocket中的会话属性到你的问答.我一直在网上搜索完全相同的问题,上面显示的方式在我看来是处理websocket中会话数据的最系统的方法.

点赞