在调用处理程序之前使用 Tomcat 8 和 Spring 4 ClassCastException 的 websockets
Posted
技术标签:
【中文标题】在调用处理程序之前使用 Tomcat 8 和 Spring 4 ClassCastException 的 websockets【英文标题】:websockets with Tomcat 8 and Spring 4 ClassCastException before handler is invoked 【发布时间】:2014-05-08 00:18:44 【问题描述】:我正在尝试让一个简单的 websocket 工作以集成到我的应用程序中。但是,在调用我的处理程序试图将 Tomcat 类型转换为 javax 对象之前,我无法让它与 Spring API 一起使用,在某处出现 ClassCastException。如果我在没有 Spring 的情况下直接使用 Tomcat(所以 javax.websocket 对象和注释)它工作得很好,所以我真的不确定为什么 Spring 会出现问题。
08-May-2014 01:10:12.048 SEVERE [http-nio-8084-exec-88] org.apache.catalina.core.StandardWrapperValve.invoke Servlet.service() for servlet [dispatcher] in context with path [/WebsocketSpringTest] threw exception [Request processing failed; nested exception is org.springframework.web.socket.server.HandshakeFailureException: Uncaught failure for request http://localhost:8084/WebsocketSpringTest/socket; nested exception is java.lang.ClassCastException: org.apache.tomcat.websocket.server.WsServerContainer cannot be cast to javax.websocket.server.ServerContainer] with root cause
java.lang.ClassCastException: org.apache.tomcat.websocket.server.WsServerContainer cannot be cast to javax.websocket.server.ServerContainer
at org.springframework.web.socket.server.standard.AbstractStandardUpgradeStrategy.getContainer(AbstractStandardUpgradeStrategy.java:67)
TestSocket.java
import org.springframework.web.socket.WebSocketHandler;
public class TestSocket implements WebSocketHandler
...
web.xml
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
调度程序-servlet.xml
<context:component-scan base-package="com.willnewbery.websocketspringtest" />
<context:annotation-config />
<mvc:annotation-driven />
<mvc:resources mapping="/resources/**" location="/resources/" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/views/" p:suffix=".jsp" />
<websocket:handlers>
<websocket:mapping path="/socket" handler="socket"/>
</websocket:handlers>
<bean id="socket" class="com.willnewbery.websocketspringtest.TestSocket"/>
pom.xml
<properties>
<endorsed.dir>$project.build.directory/endorsed</endorsed.dir>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.0.4.RELEASE</spring.version>
<tomcat.version>8.0.3</tomcat.version>
</properties>
<dependencies>
<!--javax-->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-web-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.websocket</groupId>
<artifactId>javax.websocket-api</artifactId>
<version>1.0</version>
</dependency>
<!--spring-->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>$spring.version</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>$spring.version</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>$spring.version</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>$spring.version</version>
</dependency>
<!--tomcat-->
</dependencies>
【问题讨论】:
【参考方案1】:“javax.websocket-api”依赖可能是问题所在。它已包含在服务器库中,因此您至少将其设为“已提供”范围或尝试将其删除,您很有可能在应用程序 pom 中不需要它。
【讨论】:
【参考方案2】:你从 spring-boot-starter-web 中排除了 tomcat-embed-websocket 依赖;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<artifactId>tomcat-embed-logging-juli</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
</exclusion>
<exclusion>
<artifactId>tomcat-embed-websocket</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
</exclusion>
<exclusion>
<artifactId>tomcat-embed-el</artifactId>
<groupId>org.apache.tomcat.embed</groupId>
</exclusion>
</exclusions>
</dependency>
【讨论】:
不包括tomcat-embed-websocket
单独为我工作。【参考方案3】:
你需要从war文件中排除tomcat-embed-websocket-*.jar。
将此行添加到您的 build.gradle
providedCompile("org.apache.tomcat.embed:tomcat-embed-websocket")
或在 Maven 中:
<dependency>
<groupId>org.apache.tomcat.embed</groupId>
<artifactId>tomcat-embed-websocket</artifactId>
<version>$tomcat.version</version>
</dependency>
【讨论】:
【参考方案4】:在使用 Spring Boot 构建 WAR 文件时,参考文档会指出您需要将 Tomcat 转换为提供的依赖项。 Maven 和 Gradle 的推荐做法可以在参考文档中查看 => http://docs.spring.io/spring-boot/docs/current/reference/htmlsingle/#howto-create-a-deployable-war-file
【讨论】:
以上是关于在调用处理程序之前使用 Tomcat 8 和 Spring 4 ClassCastException 的 websockets的主要内容,如果未能解决你的问题,请参考以下文章
Dubbo 2.6.8 移植指南(openEuler 20.03 LTS SP1)
Seam 2.0.2sp1 应用程序可以在嵌入 JBoss 的 Tomcat 5.5.9 上运行吗?