2016-02-29 3 views
5

я просто столкнулся своеобразную небольшую проблему:Lambda не работает WebSocket сессии

javax.websocket.Session session = //... 
// this works 
newSession.addMessageHandler(new MessageHandler.Whole<String>() { 

    @Override 
    public void onMessage(String message) { 
     MyWebSocket.this.onMessage(message); 
    } 
}); 
// these don't work 
newSession.addMessageHandler((MessageHandler.Whole<String>) MyWebSocket.this::onMessage); 
newSession.addMessageHandler((MessageHandler.Whole<String>) message -> MyWebSocket.this.onMessage(message)); 


void onMessage(String message) { 
    System.out.println(message); 
} 

Кто-нибудь знает, почему лямбда-выражения не будут работать в этом случае? Ошибка компиляции, никакого исключения, нет ничего. Метод '' onMessage '' просто не называется.

Я использую Java 1.8.0_65 и эталонную реализацию Tyrus 1.9.

ответ

2

см https://blogs.oracle.com/PavelBucek/entry/websocket_api_1_1_released

tldr; Вы должны использовать Session#addMessageHandler(Class<T> clazz, MessageHandler.Whole<T> handler)

/** 
* Register to handle to incoming messages in this conversation. A maximum of one message handler per 
* native websocket message type (text, binary, pong) may be added to each Session. I.e. a maximum 
* of one message handler to handle incoming text messages a maximum of one message handler for 
* handling incoming binary messages, and a maximum of one for handling incoming pong 
* messages. For further details of which message handlers handle which of the native websocket 
* message types please see {@link MessageHandler.Whole} and {@link MessageHandler.Partial}. 
* Adding more than one of any one type will result in a runtime exception. 
* 
* @param clazz type of the message processed by message handler to be registered. 
* @param handler whole message handler to be added. 
* @throws IllegalStateException if there is already a MessageHandler registered for the same native 
*        websocket message type as this handler. 
*/ 
public void addMessageHandler(Class<T> clazz, MessageHandler.Whole<T> handler); 

для того, чтобы использовать лямбды в качестве левшей сообщений.

-2

С моей точки зрения MessageHandler должен быть @FunctionalInterface, чтобы здесь предлагать лямбда-выражения, что не так.

+1

[«Однако компилятор будет рассматривать любой интерфейс, соответствующий определению функционального интерфейса как функционального интерфейса, независимо от того, присутствует или нет аннотация« Функциональный интерфейс »в объявлении интерфейса.»] (Https://docs.oracle. com/javase/8/docs/api/java/lang/FunctionalInterface.html) Вам не нужна аннотация, чтобы использовать его как lambda –

+1

Также была бы ошибка компиляции, если бы это было так. –