首页 > 解决方案 > javax.websocket.DeploymentException:在尝试部署到 Tomcat 时,未找到方法 [OnMessage] 上存在的消息参数的解码器

问题描述

我一直在使用 Netbeans IDE 开发我的网站,同时还使用 Glassfish/Tomcat 服务器中内置的 Netbeans,没有任何问题;但是,当我尝试将我的网站上传到托管服务器时,我在尝试部署时遇到错误,我找不到太多信息,也不知道为什么会收到此错误。我正在使用 AWS 风格的托管解决方案,我自己在服务器上安装和更新文件,而不是由托管服务提供商完成工作。我得到的错误是这样的:

SEVERE [http-nio-8080-exec-35] org.apache.catalina.core.StandardContext.startInternal Error during ServletContainerInitializer processing
javax.servlet.ServletException: javax.websocket.DeploymentException: No decoder was found for message parameters present on the method [onMessage] of class [WebsocketClass] that was annotated with OnMessage
    at org.apache.tomcat.websocket.server.WsSci.onStartup(WsSci.java:129)
    at org.apache.catalina.core.StandardContext.startInternal(StandardContext.java:5160)
    at org.apache.catalina.util.LifecycleBase.start(LifecycleBase.java:183)
    at org.apache.catalina.manager.ManagerServlet.start(ManagerServlet.java:1386)
    at org.apache.catalina.manager.HTMLManagerServlet.start(HTMLManagerServlet.java:697)
    at org.apache.catalina.manager.HTMLManagerServlet.doPost(HTMLManagerServlet.java:218)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:652)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:733)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.filters.CsrfPreventionFilter.doFilter(CsrfPreventionFilter.java:211)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.filters.HttpHeaderSecurityFilter.doFilter(HttpHeaderSecurityFilter.java:126)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.filters.SetCharacterEncodingFilter.doFilter(SetCharacterEncodingFilter.java:109)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:97)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:669)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:143)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:81)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:698)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:78)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:364)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:616)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:65)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:831)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1629)
    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)
Caused by: javax.websocket.DeploymentException: No decoder was found for message parameters present on the method [onMessage] of class [WebsocketClass] that was annotated with OnMessage
    at org.apache.tomcat.websocket.pojo.PojoMethodMapping$MessageHandlerInfo.<init>(PojoMethodMapping.java:488)
    at org.apache.tomcat.websocket.pojo.PojoMethodMapping.<init>(PojoMethodMapping.java:139)
    at org.apache.tomcat.websocket.server.WsServerContainer.addEndpoint(WsServerContainer.java:155)
    at org.apache.tomcat.websocket.server.WsServerContainer.addEndpoint(WsServerContainer.java:280)
    at org.apache.tomcat.websocket.server.WsSci.onStartup(WsSci.java:126)
    ... 38 more

至于onMessage,这是方法头,

@OnMessage
public void onMessage(Session session,EndpointConfig config, String message, @PathParam("param") String name)

根据https://docs.oracle.com/javaee/7/api/javax/websocket/Decoder.html

它说 The lifecycle of the Decoder instance is governed by the container calls to the init(javax.websocket.EndpointConfig) and destroy() methods.有了这个我假设“EndpointConfig”调用可能与这个解码器问题有关?

https://docs.oracle.com/javaee/7/api/javax/websocket/EndpointConfig.html

我确实有一些使用 Base64 解码器的实例,但那是在从 OnMessage 中调用的另一种方法中,但我认为这与此不同。

我只是不确定为什么这个问题只源于 1 个主机而不是其他主机,我也不知道如何处理这个问题。

除了使用 Netbeans IDE 中的内置服务器外,我还尝试使用我已经设置的另一个托管解决方案,该主机由公司自己管理,预装了 Tomcat,它使用 C-Panel。将站点部署到该 Tomcat 实例似乎可以正常工作,因为在部署时我在该服务器上的 Catalina.out 文件中没有收到任何错误。

我想知道是否有人对导致此错误的原因有任何想法?我假设我在服务器上安装 Tomcat 时可能搞砸了,也许 Server.xml 文件是问题所在?我只是觉得奇怪的是它与 WebSockets 有关系,但如果是这样的话……这就是我在 Netbeans 内置服务器和托管托管解决方案与我管理的解决方案之间所能想到的全部。

任何帮助表示赞赏,谢谢!

标签: javatomcatservletswebsocketweb-deployment

解决方案


服务器正在抱怨该EndpointConfig参数,这是不允许的。你可以有:

  • 最多一个参数来接收消息内容(参见OnMessage Javadoc以获取类型列表)。默认支持一些类型,剩下的你需要一个Decoder
  • 多个@PathParam带注释String的参数,
  • 一个可选Session参数。

EndpointConfig带注释的方法的签名中允许使用参数@OnOpen,因此可能会造成混淆。


推荐阅读