在 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 ServerHttpHandlerServletContextHandlerdoHandle的第一行检查请求是否是WebSocket升级请求,如果是则立即returns(在这种情况下它被传递WebSocketServletServletContextHandler

我有一个设置会话属性的简单 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) 调用)。