Я пытался разработать веб-приложение со встроенным Tomcat, у которого есть @WebServlet
(для обслуживания веб-страниц и запросов RESTful) и @ServerEndpoint
(веб-сокет).Пока что все работает нормально на моем 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);
}
}
И моя конечная точка веб-сокета определяется следующим образом:
@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
таких проблем не было.Я также проверил, проверил, загружен ли класс 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, чего я не делал.