问题描述
我需要从 @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中,由在 http://docs.oracle.com/javaee/7/api/javax/websocket/server/ServerEndpoint.html\"rel =noreferrer> @ServerEndpoint
一>。 ServletContext
依次可以通过。这是一石二鸟。
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.
为了捕获握手请求,实现一个并覆盖方法。 HandshakeRequest
在这里可用作方法参数。您可以将 HttpSession
放入。 EndpointConfig
又可作为方法参数。
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);
}
}
以下是如何使用它,请注意属性:
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),您可以从(链接位于展示的最底部) )。
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!