访问JSR-356 @ServerEndpoint的@OnMessage中的ServletContext和HttpSession [英] Accessing ServletContext and HttpSession in @OnMessage of a JSR-356 @ServerEndpoint

查看:175
本文介绍了访问JSR-356 @ServerEndpoint的@OnMessage中的ServletContext和HttpSession的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从 @ServerEndpoint 中获取 ServletContext 才能找到Spring ApplicationContext 并查找Bean。

I need to get the ServletContext from inside a @ServerEndpoint in order to find Spring ApplicationContext and lookup for a Bean.

目前我的最佳方法是在JNDI命名上下文中绑定该bean并在其中查找端点。欢迎任何更好的解决方案。

For the moment my best approach is to bind that bean in the JNDI naming context and lookup it in the Endpoint. Any better solution is welcome.

我也在寻找一种合理的方法来同步servlet的 HttpSession 与websocket的会话

I'm also looking for a reasonable way to sync servlet's HttpSession with websocket's Session.

推荐答案

servlet HttpSession 在JSR-356中,由 HandshakeRequest#getHttpSession() @OnOpen http://docs.oracle.com/javaee/7/api/javax/websocket/server/ServerEndpoint.html\"rel =noreferrer> @ServerEndpoint ServletContext 依次可以通过 HttpSession#getServletContext() 。这是一石二鸟。

The servlet HttpSession is in JSR-356 available by HandshakeRequest#getHttpSession() which is in turn available when a handshake request is made right before @OnOpen of a @ServerEndpoint. The ServletContext is in turn just available via HttpSession#getServletContext(). That's two birds with one stone.

为了捕获握手请求,实现一个 ServerEndpointConfig.Configurator 并覆盖 modifyHandshake() 方法。 HandshakeRequest 在这里可用作方法参数。您可以将 HttpSession 放入 EndpointConfig#getUserProperties() EndpointConfig 又可作为方法参数 @OnOpen

In order to capture the handshake request, implement a ServerEndpointConfig.Configurator and override the modifyHandshake() method. The HandshakeRequest is here available as method argument. You can put the HttpSession into EndpointConfig#getUserProperties(). The EndpointConfig is in turn available as method argument @OnOpen.

以下是<$的启动示例c $ c> ServerEndpointConfig.Configurator implementation:

Here's a kickoff example of the ServerEndpointConfig.Configurator implementation:

public class ServletAwareConfig extends ServerEndpointConfig.Configurator {

    @Override
    public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
        HttpSession httpSession = (HttpSession) request.getHttpSession();
        config.getUserProperties().put("httpSession", httpSession);
    }

}

以下是如何使用它,请注意 $ code> @ServerEndpoint 属性:

Here's how you can use it, note the configurator attribute of the @ServerEndpoint:

@ServerEndpoint(value="/your_socket", configurator=ServletAwareConfig.class)
public class YourSocket {

    private EndpointConfig config;

    @OnOpen
    public void onOpen(Session websocketSession, EndpointConfig config) {
        this.config = config;
    }

    @OnMessage
    public void onMessage(String message) {
        HttpSession httpSession = (HttpSession) config.getUserProperties().get("httpSession");
        ServletContext servletContext = httpSession.getServletContext();
        // ...
    }

}

作为设计提示,最好保持 @ServerEndpoint 完全不受servlet API依赖性的影响。您可以在 modifyHandshake()实现中更好地立即从servlet会话或上下文中提取您需要的 信息(通常是可变的Javabean)将它们放在用户属性映射中。如果你不这样做,那么你应该记住,websocket会话可以比HTTP会话更长寿。因此,当您仍然将 HttpSession 带入端点时,当您尝试访问时,可能会遇到 IllegalStateException 它已经过期了。

As a design hint, it's the best to keep your @ServerEndpoint fully free of servlet API dependencies. You'd in the modifyHandshake() implementation better immediately extract exactly that information (usually a mutable Javabean) you need from the servlet session or context and put them in the user properties map instead. If you don't do that, then you should keep in mind that a websocket session can live longer than the HTTP session. So when you still carry around HttpSession into the endpoint, then you may run into IllegalStateException when you try to access it while it's being expired.

如果您碰巧有CDI(也许还有JSF),您可以从 OmniFaces < o:socket> (链接位于展示的最底部) )。

In case you happen to have CDI (and perhaps JSF) at hands, you may get inspiration from the source code of OmniFaces <o:socket> (links are at very bottom of showcase).

  • Real time updates from database using JSF/Java EE
  • Notify only specific user(s) through WebSockets, when something is modified in the database

这篇关于访问JSR-356 @ServerEndpoint的@OnMessage中的ServletContext和HttpSession的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆