在 WebSocketServlet (Jetty WebSockets) 中访问在 HttpServlet 中设置的会话属性
Accessing session attributes set in a HttpServlet in a WebSocketServlet (Jetty WebSockets)
我正在尝试从 WebSocketServlet
访问 HttpServlet
中设置的会话属性
我有两个 ServletContextHandler
对象,都启用了 SESSIONS
:
val httpHandler = object : ServletContextHandler(nullParent, contextPath, SESSIONS).apply {
addServlet(ServletHolder(httpServlet), "/*")
}
val webSocketHandler = ServletContextHandler(nullParent, contextPath, SESSIONS).apply {
addServlet(ServletHolder(wsServlet), "/*")
}
这些作为 HandlerList(httpHandler, webSocketHandler)
附加到我的 Jetty Server
。 HttpHandler
的ServletContextHandler
的doHandle
的第一行检查请求是否是WebSocket升级请求,如果是则立即returns(在这种情况下它被传递WebSocketServlet
的 ServletContextHandler
。
我有一个设置会话属性的简单 POST
端点,但我无法在 WebSocketServlet
中检索此会话属性:
class MyWsServlet : WebSocketServlet() {
override fun configure(factory: WebSocketServletFactory) {
factory.creator = WebSocketCreator { req, res ->
// session exists here, but req.session.getAttribute("any-attr") is always null
}
}
override fun service(req: HttpServletRequest, res: HttpServletResponse) {
// session also exists here, but req.session.getAttribute("any-attr") is always null
}
}
欢迎提出任何意见或建议。
编辑:在调用 req.session.setAttribute("test", "tast")
之后,我包含了一些来自 GET 请求与 WebSocket 请求的调试信息:
Path: /
Cookies:{JSESSIONID=node01cxyhb0addjwikyb2lgtnlxlw0.node0}
Session: Session@24b04e4{id=node01cxyhb0addjwikyb2lgtnlxlw0,x=node01cxyhb0addjwikyb2lgtnlxlw0.node0,req=1,res=true}
Session id: node01cxyhb0addjwikyb2lgtnlxlw0
Session isNew: false
Session attributes: {test=tast}
---------------------------
Path: /websocket
Cookies:{JSESSIONID=node01cxyhb0addjwikyb2lgtnlxlw0.node0}
Session: Session@5989f3d1{id=node01cxyhb0addjwikyb2lgtnlxlw0,x=node01cxyhb0addjwikyb2lgtnlxlw0.node0,req=1,res=true}
Session id: node01cxyhb0addjwikyb2lgtnlxlw0
Session isNew: false
Session attributes: {}
首先,摆脱你的 2 ServletContextHandler
,使用一个。无论如何,您不能在同一个 contextPath 上有两个处理程序。
此外,您有 2 种主要方法可以实现 Jetty 服务器 WebSocket,使用 WebSocketServlet
,或使用 WebSocketUpgradeFilter
。最大的区别是使用 WebSocketUpgradeFilter
你可以有多个映射指向任意数量的 WebSocket 端点,使用 Servlet url-pattern 符号,或 URI-template 符号,甚至正则表达式符号。
如果您这样做后问题仍然存在,那么听起来您的客户要么没有发送 Jetty 需要的 Cookie
header,要么发送了错误的(例如:a Cookie
header 指向不同的/新的 HttpSession
引用)。
捕获客户端和服务器之间的流量,注意客户端 Cookie
值,以及在服务器响应中看到的任何 Set-Cookie
值。
您也可以有一个过滤器,它只转储每个请求的活动 HttpSession
详细信息。确保它显示 HttpSession.getId()
、HttpSession.isNew()
并转储所有属性(通过组合 .getAttributeNames()
和 getAttribute(String name)
调用)。
我正在尝试从 WebSocketServlet
HttpServlet
中设置的会话属性
我有两个 ServletContextHandler
对象,都启用了 SESSIONS
:
val httpHandler = object : ServletContextHandler(nullParent, contextPath, SESSIONS).apply {
addServlet(ServletHolder(httpServlet), "/*")
}
val webSocketHandler = ServletContextHandler(nullParent, contextPath, SESSIONS).apply {
addServlet(ServletHolder(wsServlet), "/*")
}
这些作为 HandlerList(httpHandler, webSocketHandler)
附加到我的 Jetty Server
。 HttpHandler
的ServletContextHandler
的doHandle
的第一行检查请求是否是WebSocket升级请求,如果是则立即returns(在这种情况下它被传递WebSocketServlet
的 ServletContextHandler
。
我有一个设置会话属性的简单 POST
端点,但我无法在 WebSocketServlet
中检索此会话属性:
class MyWsServlet : WebSocketServlet() {
override fun configure(factory: WebSocketServletFactory) {
factory.creator = WebSocketCreator { req, res ->
// session exists here, but req.session.getAttribute("any-attr") is always null
}
}
override fun service(req: HttpServletRequest, res: HttpServletResponse) {
// session also exists here, but req.session.getAttribute("any-attr") is always null
}
}
欢迎提出任何意见或建议。
编辑:在调用 req.session.setAttribute("test", "tast")
之后,我包含了一些来自 GET 请求与 WebSocket 请求的调试信息:
Path: /
Cookies:{JSESSIONID=node01cxyhb0addjwikyb2lgtnlxlw0.node0}
Session: Session@24b04e4{id=node01cxyhb0addjwikyb2lgtnlxlw0,x=node01cxyhb0addjwikyb2lgtnlxlw0.node0,req=1,res=true}
Session id: node01cxyhb0addjwikyb2lgtnlxlw0
Session isNew: false
Session attributes: {test=tast}
---------------------------
Path: /websocket
Cookies:{JSESSIONID=node01cxyhb0addjwikyb2lgtnlxlw0.node0}
Session: Session@5989f3d1{id=node01cxyhb0addjwikyb2lgtnlxlw0,x=node01cxyhb0addjwikyb2lgtnlxlw0.node0,req=1,res=true}
Session id: node01cxyhb0addjwikyb2lgtnlxlw0
Session isNew: false
Session attributes: {}
首先,摆脱你的 2 ServletContextHandler
,使用一个。无论如何,您不能在同一个 contextPath 上有两个处理程序。
此外,您有 2 种主要方法可以实现 Jetty 服务器 WebSocket,使用 WebSocketServlet
,或使用 WebSocketUpgradeFilter
。最大的区别是使用 WebSocketUpgradeFilter
你可以有多个映射指向任意数量的 WebSocket 端点,使用 Servlet url-pattern 符号,或 URI-template 符号,甚至正则表达式符号。
如果您这样做后问题仍然存在,那么听起来您的客户要么没有发送 Jetty 需要的 Cookie
header,要么发送了错误的(例如:a Cookie
header 指向不同的/新的 HttpSession
引用)。
捕获客户端和服务器之间的流量,注意客户端 Cookie
值,以及在服务器响应中看到的任何 Set-Cookie
值。
您也可以有一个过滤器,它只转储每个请求的活动 HttpSession
详细信息。确保它显示 HttpSession.getId()
、HttpSession.isNew()
并转储所有属性(通过组合 .getAttributeNames()
和 getAttribute(String name)
调用)。