使用 Lambda 添加 MessageHandler NullPointerException

addMessageHandler NullPointerException with Lambda

Tomcat 8.0.21

这个有效:

session.addMessageHandler(new MessageHandler.Whole<String>() {
            @Override
            public void onMessage(String string) {
                try {
                    session.getBasicRemote().sendText(string);
                } catch (IOException ex) {
                    Logger.getLogger(WebSocket.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });

这不是:

session.addMessageHandler((MessageHandler.Whole<String>) (String string) -> {
            try {
                session.getBasicRemote().sendText(string);
            } catch (IOException ex) {
                Logger.getLogger(WebSocket.class.getName()).log(Level.SEVERE, null, ex);
            }
        });

我可以假设这是一个 tomcat 错误吗?

java.lang.NullPointerException
    at org.apache.tomcat.websocket.Util.getGenericType(Util.java:192)
    at org.apache.tomcat.websocket.Util.getGenericType(Util.java:212)
    at org.apache.tomcat.websocket.Util.getGenericType(Util.java:212)
    at org.apache.tomcat.websocket.Util.getMessageType(Util.java:171)
    at org.apache.tomcat.websocket.WsSession.addMessageHandler(WsSession.java:198)
    at org.apache.tomcat.websocket.server.WsHttpUpgradeHandler.init(WsHttpUpgradeHandler.java:138)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:696)
    at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:223)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1517)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1474)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

不确定您使用的 Tomcat 是哪个版本,但它可能已经被修复:https://bz.apache.org/bugzilla/show_bug.cgi?format=multiple&id=57788

此外,您调用的方法使用原始类型,并非在所有情况下都有效。从 Tomcat JavadocaddMessageHandler(MessageHandler):

The message type will be derived at runtime from the provided MessageHandler instance. It is not always possible to do this so it is better to use addMessageHandler(Class, javax.websocket.MessageHandler.Partial) or addMessageHandler(Class, javax.websocket.MessageHandler.Whole).

试试这个:

session.addMessageHandler(String.class, (String string) -> { ... } )