嵌入式 Tomcat 给出“不允许 HTTP 升级到 WebSocket”错误
Posted
技术标签:
【中文标题】嵌入式 Tomcat 给出“不允许 HTTP 升级到 WebSocket”错误【英文标题】:Embedded Tomcat gives "did not permit the HTTP upgrade to WebSocket" error 【发布时间】:2018-11-25 05:23:22 【问题描述】:我一直在尝试开发一个带有 @WebServlet
(用于提供网页和 RESTful 请求)和 @ServerEndpoint
(websocket)的嵌入式 Tomcat 的 webapp。到目前为止,它在我的 Intellij 上运行良好。但是,当我使用 Maven 构建代码并改为执行 jar 文件时。我总是收到以下错误:
原因:javax.websocket.DeploymentException:来自服务器的 HTTP 响应 [HTTP/1.1 404 Not Found] 不允许 HTTP 升级到 WebSocket
错误追溯到我的套接字客户端,我试图打开一个连接:
container.connectToServer(this, endpointURI);
供您参考,客户端的外观如下:
@ClientEndpoint
public class SocketClient
Session userSession = null;
private MessageHandler messageHandler;
public SocketClient(URI endpointURI)
try
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
container.connectToServer(this, endpointURI);
catch (Exception e)
throw new RuntimeException(e);
@OnOpen
public void onOpen(Session userSession)
System.out.println("opening websocket");
this.userSession = userSession;
@OnClose
public void onClose(Session userSession, CloseReason reason)
System.out.println("closing websocket");
this.userSession = null;
@OnMessage
public void onMessage(String message)
if (this.messageHandler != null)
this.messageHandler.handleMessage(message);
public void addMessageHandler(MessageHandler msgHandler)
this.messageHandler = msgHandler;
public void sendMessage(String message)
this.userSession.getAsyncRemote().sendText(message);
public static interface MessageHandler
public void handleMessage(String message);
而我的 websocket 端点定义如下:
@ServerEndpoint(
value="/hi",
decoders = MessageDecoder.class,
encoders = MessageEncoder.class )
public class SocketEndpoint
private Session session;
private static Set<SocketEndpoint> chatEndpoints
= new CopyOnWriteArraySet<>();
public SocketEndpoint()
System.out.println("class loaded " + this.getClass());
@OnOpen
public void onOpen(Session session)
this.session = session;
chatEndpoints.add(this);
System.out.println(session.getId() + " has open a connection");
try
session.getBasicRemote().sendText("Connection Established");
catch (IOException ex)
ex.printStackTrace();
@OnMessage
public void onMessage(Message message, Session session) /* ... */
@OnClose
public void onClose(Session session) /* ... */
@OnError
public void onError(Session session, Throwable throwable) /* ... */
就像我说的,当我在 Intellij 上运行代码时它运行良好,但有趣的是,当我将鼠标悬停在 SocketEndpoint
上时,我会得到一个工具提示,说这个类从未使用过,而其他 HttpServlet
类他们没有使用t有这样的问题。我还通过检查 SocketEndpoint
类是否已加载(查看构造函数)来验证,当我执行 jar 时它没有加载。
以及任何需要的依赖项(可能)我已经添加了它们(pom.xml):
<properties>
<tomcat.version>8.0.28</tomcat.version>
<gson.version>2.8.0</gson.version>
<junit.jupiter.version>5.2.0</junit.jupiter.version>
<junit.platform.version>1.2.0</junit.platform.version>
<junit.vintage.version>5.2.0</junit.vintage.version>
<log4j2.version>2.8.2</log4j2.version>
<maven-surefire-plugin.version>2.21.0</maven-surefire-plugin.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-core</artifactId>
<version>$tomcat.version</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-jasper</artifactId>
<version>$tomcat.version</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-logging-juli</artifactId>
<version>$tomcat.version</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper</artifactId>
<version>$tomcat.version</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper-el</artifactId>
<version>$tomcat.version</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jsp-api</artifactId>
<version>$tomcat.version</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-websocket</artifactId>
<version>$tomcat.version</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jasper-el</artifactId>
<version>$tomcat.version</version>
</dependency>
<dependency>
<groupId>org.apache.tomcat</groupId>
<artifactId>tomcat-jsp-api</artifactId>
<version>$tomcat.version</version>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-engine</artifactId>
<version>$junit.platform.version</version>
</dependency>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-runner</artifactId>
<version>$junit.platform.version</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>$junit.vintage.version</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-migrationsupport</artifactId>
<version>$junit.vintage.version</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-client-api</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>$log4j2.version</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.googlecode.json-simple/json-simple -->
<dependency>
<groupId>com.googlecode.json-simple</groupId>
<artifactId>json-simple</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>$gson.version</version>
</dependency>
</dependencies>
任何帮助将不胜感激。我看到大多数遇到类似问题的人都在使用 Spring,而我没有。
【问题讨论】:
【参考方案1】:错误显示为您的客户端尝试连接到未找到的 Web 套接字 (URL)。
Caused by: javax.websocket.DeploymentException: The HTTP response from the server [HTTP/1.1 404 Not Found] did not permit the HTTP upgrade to WebSocket
确保您在应用程序中提及任何上下文路径或找到确切的 websocket URL。
【讨论】:
以上是关于嵌入式 Tomcat 给出“不允许 HTTP 升级到 WebSocket”错误的主要内容,如果未能解决你的问题,请参考以下文章
Spring Boot - 当我调用 API 时,它给出 404 错误
Tomcat专题-----Tomcat源码嵌入式Tomcat