java - 将自定义配置器与 WebSocket 一起使用
问题描述
关于扩展 ServerEndpointConfig.Configurator 以覆盖 Tomcat 在接收 WebSocket 请求时实例化带有 @ServerEndpoint 注释的 POJO 类的默认操作的快速问题。我这样做的原因是我的端点类依赖于 IoC 依赖注入,因此需要从注册表中获取它的依赖项。
我的配置器方法:
@Override
public <T> T getEndpointInstance(Class<T> endpointClass) throws InstantiationException {
return endpointClass.cast(RegistryProxy.getService(HarbourServerEndpoint.class));
}
@ServerEndpoint 注释放在我的 HarbourServerEndpointImpl POJO 类上,而不是它实现的接口上。根据下面的运行时 catalina.out 错误消息,问题似乎是注册表返回 HarbourServerEndpoint 而 Tomcat 期待 HarbourServerEndpointImpl 的实例?
我希望有人可以解释我的自定义配置器出了什么问题。
2019 年 4 月 15 日 12:45:28.488 严重 [http-nio-8080-exec-915] org.apache.coyote.AbstractProtocol$ConnectionHandler.process 读取请求时出错,忽略 java.lang.ClassCastException:无法将 $HarbourServerEndpoint_39c9cc24eb8b2a 转换为 com .optomus.harbour.services.HarbourServerEndpointImpl at java.lang.Class.cast(Class.java:3369) at com.optomus.harbour.services.HarbourServerEndpointConfigurator.getEndpointInstance(HarbourServerEndpointConfigurator.java:17) at org.apache.tomcat.websocket .pojo.PojoEndpointServer.onOpen(PojoEndpointServer.java:44)
at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:133) at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:846) at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1471) at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) at java.lang.Thread.run(Thread.java:748)
最后,完全没有强制转换,编译器给出了错误:
Error:(17, 40) java: incompatible types: inference variable T has incompatible bounds equality constraints: com.optomus.harbour.services.HarbourServerEndpoint upper bounds: T,java.lang.Object
解决方案
自从发布这个问题以来,我研究了 Tapestry-IoC 及其工作原理。事实证明,返回的内容看起来有点奇怪($HarbourServerEndpoint_39c9cc24eb8b2a)是有原因的。它是一个服务代理对象,而不是我所期望的服务实现的实例。我不确定这对于 IoC 容器有多典型。引用 Tapestry 网站:
“服务由两个主要部分组成:服务接口和服务实现。
服务接口是服务将如何在注册表的其余部分中表示。由于传递的通常是代理,因此您不能期望将服务对象强制转换为实现类(您会看到 ClassCastException)。换句话说,您应该小心确保您的服务接口是完整的,因为 Tapestry IoC 有效地将您与 casts 等后门隔离开来。”
这使得从使用@ServerEndpoint 注释的类的 IoC 注册表实例中获取相当棘手,我现在正在探索其他选项。
问候,
克里斯。
推荐阅读
- java - Spring 中 JPA 存储库的接口投影的最佳实践?
- php - 带有远程(docker)php 解释器的 Visual Studio Code
- c# - RegularExpressionValidator.ValidationExpression 文本应以
- java - 如何在清理和构建时解决错误
- c# - 如何在没有自定义操作的情况下升级 WPF 文件作为鼠标单击
- node.js - Heroku 上的图像损坏 - NodeJS React 应用程序
- ruby-on-rails - 条带未定义方法 customer_id
- python - 图表断开:无法获取张量的值 Tensor("input_2:0", shape=(?, 500, 500, 5, 1)
- android - 是否可以在工作管理器中安排事件(GPS 开/关、Wifi 开?关)?
- postgresql - PostgreSQL 子查询/CTE 是否被缓存?