我想在websocket handshake \ session与HttpSession对象之间建立连接。
我使用了以下握手修改:
public class GetHttpSessionConfigurator extends ServerEndpointConfig.Configurator
{
@Override
public void modifyHandshake(ServerEndpointConfig config,
HandshakeRequest request,
HandshakeResponse response)
{
HttpSession httpSession = (HttpSession)request.getHttpSession();
config.getUserProperties().put(HttpSession.class.getName(),httpSession);
}
}
正如这篇文章中提到的:
从Web Socket @ServerEndpoint中的HttpServletRequest访问HttpSession
现在,
由于某些原因,握手时,(HttpSession)request.getHttpSession()始终返回null。
这是我的客户端代码:
<!DOCTYPE html>
<html>
<head>
<title>Testing websockets</title>
</head>
<body>
<div>
<input type="submit" value="Start" onclick="start()" />
</div>
<div id="messages"></div>
<script type="text/javascript">
var webSocket =
new WebSocket('ws://localhost:8080/com-byteslounge-websockets/websocket');
webSocket.onerror = function(event) {
onError(event)
};
webSocket.onopen = function(event) {
onOpen(event)
};
webSocket.onmessage = function(event) {
onMessage(event)
};
function onMessage(event) {
document.getElementById('messages').innerHTML
+= '<br />' + event.data;
}
function onOpen(event) {
document.getElementById('messages').innerHTML
= 'Connection established';
}
function onError(event) {
alert(event.data);
}
function start() {
webSocket.send('hello');
return false;
}
</script>
</body>
</html>
为什么没有创建会话的任何想法?
谢谢
这是预期的行为,但我同意这可能令人困惑。来自HandshakeRequest.getHttpSession的javadoc:
/**
* Return a reference to the HttpSession that the web socket handshake that
* started this conversation was part of, if the implementation
* is part of a Java EE web container.
*
* @return the http session or {@code null} if either the websocket
* implementation is not part of a Java EE web container, or there is
* no HttpSession associated with the opening handshake request.
*/
问题是,尚未为您的客户端连接创建HttpSession,而WebSocket API实现只是询问是否创建了某些内容,如果没有,则为 不创造它。你需要做的就是打电话 httpServletRequest.getSession()
某时 之前 调用WebSocket impl过滤器(doFilter(...)
叫做)。
这可以通过例如调用所提到的方法来实现 ServletRequestListener#requestInitalized
或在不同的过滤器等。
这是Pavel Bucek的答案的一个impl,在添加之后,我得到了我的会话
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
@WebListener
public class RequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent sre) {
// TODO Auto-generated method stub
}
@Override
public void requestInitialized(ServletRequestEvent sre) {
((HttpServletRequest) sre.getServletRequest()).getSession();
}
}
建立在 @ pavel-bucek的回答,我写了一篇 简单 HttpSessionInitializerFilter
servlet过滤器。
只需从“Releases”页面下载jar并将其保存在类路径中的任何位置,然后将以下代码段添加到web.xml描述符中(根据需要修改url-pattern):
<filter>
<filter-name>HttpSessionInitializerFilter</filter-name>
<filter-class>net.twentyonesolutions.servlet.filter.HttpSessionInitializerFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HttpSessionInitializerFilter</filter-name>
<url-pattern>/ws/*</url-pattern>
</filter-mapping>
第一:创建一个新类
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
@WebListener
public class RequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
((HttpServletRequest)servletRequestEvent.getServletRequest()).getSession();
}
}
然后在App main上添加“ServletComponentScan”注释:
@SpringBootApplication
@ServletComponentScan
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}