Java 这是否可以在同一上下文中为websocket处理程序和普通servlet提供服务器?

Java 这是否可以在同一上下文中为websocket处理程序和普通servlet提供服务器?,java,servlets,websocket,servlet-filters,spring-websocket,Java,Servlets,Websocket,Servlet Filters,Spring Websocket,这是否可以在同一上下文中为websocket处理程序和普通servlet提供服务 样本 我试过多种方法,但都做不到。似乎url映射是通过上下文路径过滤的,而不是通过“http”或“ws”之类的协议过滤的。可能是我发现的不对。我试图使用spring和java来了解这一点。简短回答: 不,您不能使用servlet或websocket提供的相同路径。对http://localhost/appcontext/endpoint应具有特定的行为 长答覆: 这个答案超出了Java的范围,因为它主要依赖于web

这是否可以在同一上下文中为websocket处理程序和普通servlet提供服务

样本

我试过多种方法,但都做不到。似乎url映射是通过上下文路径过滤的,而不是通过“http”或“ws”之类的协议过滤的。可能是我发现的不对。我试图使用spring和java来了解这一点。

简短回答: 不,您不能使用servlet或websocket提供的相同路径。对
http://localhost/appcontext/endpoint
应具有特定的行为

长答覆: 这个答案超出了Java的范围,因为它主要依赖于websocket圣经。原因在于握手过程

Websocket URI

在RFC 6455的第3节中,websocket URI的定义如下:

ws-URI=“ws:”“/”主机[”:“端口]路径[“?”查询]

wss URI=“wss:”“/”主机[”:“端口]路径[“?”查询]

撇开URI的细节不谈,人们可能会认为只使用HTTP协议就可以访问HTTP对应项

握手:客户端

提醒:websocket是一种双向协议。因此,客户端是初始化连接的实体。但是,一旦建立连接,客户端和服务器都可以发送消息或关闭通信。但是服务器和客户机的概念是为了知道谁是谁

客户端初始化握手:“嘿,服务器!我想建立webosocket通信”。但是,握手是从http开始的。RFC 6455第17页(第4.1节):

  • 握手必须是[RFC2616]指定的有效HTTP请求

  • 请求的方法必须是GET,HTTP版本必须至少为1.1

    例如,如果WebSocket URI是“ws://example.com/chat”,则发送的第一行应该是“GET/chat HTTP/1.1”

  • 请求的“请求URI”部分必须与第3节(相对URI)中定义的/resource name/匹配,或者是一个绝对http/https URI,在解析时,该URI具有与相应ws/wss URI匹配的/resource name/、/host/、和/port/

  • 在每个websocket通信初始化的背后都隐藏着相同路径的HTTP请求。回到您的示例:

  • 客户端询问
    ws://localhost/appcontext/endpoint
  • 它实际上要求
    http://localhost/appcontext/endpoint
    带有升级请求和RFC 6455定义的适当标题
  • 服务器应答,只有在握手之后,通信才会从
    http(s)
    切换到
    ws(s)
  • 握手:服务器端

    但是如果你想作弊并说“我假装我不知道这是一个websocket URI,我想访问这个URL后面的HTTP资源”,那该怎么办呢。在服务器端,应用程序已注册路径
    http://localhost/appcontext/endpoint
    用于URI匹配,如“我在这里等待websocket连接”,类似于web服务路径匹配过程。在RFC 6455第4.2.1节中:

    客户的开场握手包括以下几个部分。如果服务器在读取握手时发现客户端未发送与以下描述匹配的握手(请注意,根据[RFC2616],头字段的顺序并不重要),包括但不限于任何违反为握手组件指定的ABNF语法的行为,服务器必须停止处理客户端的握手,并返回带有适当错误代码的HTTP响应(例如400错误请求)

  • HTTP/1.1或更高版本的GET请求,包括“请求URI”[RFC2616],应解释为第3节中定义的/resource name/(或包含/resource name/)的绝对HTTP/HTTPS URI)

  • 包含服务器权限的|主机|头字段

  • 包含值“websocket”的| Upgrade |标头字段,被视为ASCII不区分大小写的值

  • As
    http://localhost/appcontext/endpoint
    注册用于websocket握手,基本HTTP请求不包括
    升级
    头,然后被服务器拒绝

    编辑 在写这个答案时,我尝试了以下方法:

  • 端点:
    appcontext/Endpoint
  • 页面:
    appcontext/endpoint/index.xhtml
  • 欢迎文件:
    index.xhtml
    :因此
    appcontext/endpoint
    重定向到
    index.xhtml
  • 正如所料,我的websocket连接失败。如果我将页面路径从
    endpoint/index.xhtml
    更改为
    endpoint2/index.xhtml
    ,websocket将恢复工作

    但是,我刚刚发现它的websocket连接使用相同的URL,我找不到原因>\u简短回答: 不,您不能使用servlet或websocket提供的相同路径。对
    http://localhost/appcontext/endpoint
    应具有特定的行为

    长答覆: 这个答案超出了Java的范围,因为它主要依赖于websocket圣经。原因在于握手过程

    Websocket URI

    在RFC 6455的第3节中,websocket URI的定义如下:

    ws-URI=“ws:”“/”主机[”:“端口]路径[“?”查询]

    wss URI=“wss:”“/”主机[”:“端口]路径[“?”查询]

    撇开URI的细节不谈,人们可能会认为只使用HTTP协议就可以访问HTTP对应项

    握手:客户端

    提醒:websocket是一种双向协议。因此,客户端是初始化连接的实体。但是,一旦建立连接,客户端和服务器都可以发送me
    http://localhost/appcontext/endpoint  --> serving by normal servlet
    ws://localhost/appcontext/endpoint --> serving by websocket handler