From 861ab900aeb9c61b0f7271f06ae06a27e66d7d46 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 26 Apr 2013 12:04:45 -0400 Subject: [PATCH] Switch to single message method for WebSocketHandler --- .../sockjs/AbstractSockJsSession.java | 10 +-- .../sockjs/SockJsSessionFactory.java | 2 +- .../server/AbstractServerSockJsSession.java | 2 +- .../sockjs/server/AbstractSockJsService.java | 6 +- .../sockjs/server/SockJsService.java | 2 +- .../sockjs/server/TransportHandler.java | 2 +- .../server/support/DefaultSockJsService.java | 6 +- .../support/SockJsHttpRequestHandler.java | 6 +- ...AbstractHttpReceivingTransportHandler.java | 2 +- .../AbstractHttpSendingTransportHandler.java | 2 +- .../AbstractHttpServerSockJsSession.java | 2 +- .../EventSourceTransportHandler.java | 2 +- .../transport/HtmlFileTransportHandler.java | 2 +- .../JsonpPollingTransportHandler.java | 2 +- .../transport/PollingServerSockJsSession.java | 2 +- .../transport/SockJsWebSocketHandler.java | 12 +-- .../StreamingServerSockJsSession.java | 2 +- .../transport/WebSocketTransportHandler.java | 8 +- .../transport/XhrPollingTransportHandler.java | 2 +- .../XhrStreamingTransportHandler.java | 2 +- .../websocket/BinaryMessage.java | 2 - .../BinaryWebSocketHandlerAdapter.java | 38 --------- .../TextWebSocketHandlerAdapter.java | 39 --------- .../websocket/WebSocketHandler.java | 21 +++-- .../websocket/WebSocketMessage.java | 8 +- .../AbstractWebSocketSesssionAdapter.java | 83 +++++++++++++++++++ .../BinaryWebSocketHandlerAdapter.java | 50 +++++++++++ .../JettyWebSocketListenerAdapter.java | 13 +-- .../adapter/JettyWebSocketSessionAdapter.java | 27 ++---- .../adapter/StandardEndpointAdapter.java | 36 ++++---- .../StandardWebSocketSessionAdapter.java | 39 ++------- .../TextWebSocketHandlerAdapter.java} | 23 ++--- .../adapter/WebSocketHandlerAdapter.java | 70 ++++++++++++++++ .../adapter/WebSocketHandlerInvoker.java | 63 +++++++------- .../websocket/adapter/package-info.java | 5 +- .../websocket/client/WebSocketClient.java | 4 +- .../client/WebSocketConnectionManager.java | 6 +- .../endpoint/StandardWebSocketClient.java | 6 +- .../server/DefaultHandshakeHandler.java | 2 +- .../websocket/server/HandshakeHandler.java | 2 +- .../server/RequestUpgradeStrategy.java | 2 +- .../AbstractEndpointUpgradeStrategy.java | 8 +- .../support/JettyRequestUpgradeStrategy.java | 8 +- .../support/WebSocketHttpRequestHandler.java | 8 +- 44 files changed, 358 insertions(+), 281 deletions(-) delete mode 100644 spring-websocket/src/main/java/org/springframework/websocket/BinaryWebSocketHandlerAdapter.java delete mode 100644 spring-websocket/src/main/java/org/springframework/websocket/TextWebSocketHandlerAdapter.java create mode 100644 spring-websocket/src/main/java/org/springframework/websocket/adapter/AbstractWebSocketSesssionAdapter.java create mode 100644 spring-websocket/src/main/java/org/springframework/websocket/adapter/BinaryWebSocketHandlerAdapter.java rename spring-websocket/src/main/java/org/springframework/websocket/{WebSocketHandlerAdapter.java => adapter/TextWebSocketHandlerAdapter.java} (54%) create mode 100644 spring-websocket/src/main/java/org/springframework/websocket/adapter/WebSocketHandlerAdapter.java diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/AbstractSockJsSession.java b/spring-websocket/src/main/java/org/springframework/sockjs/AbstractSockJsSession.java index 9b1e07c99f9..d105a16d6af 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/AbstractSockJsSession.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/AbstractSockJsSession.java @@ -57,7 +57,7 @@ public abstract class AbstractSockJsSession implements WebSocketSession { * @param sessionId * @param handlerProvider the recipient of SockJS messages */ - public AbstractSockJsSession(String sessionId, HandlerProvider handlerProvider) { + public AbstractSockJsSession(String sessionId, HandlerProvider> handlerProvider) { Assert.notNull(sessionId, "sessionId is required"); Assert.notNull(handlerProvider, "handlerProvider is required"); this.sessionId = sessionId; @@ -136,12 +136,12 @@ public abstract class AbstractSockJsSession implements WebSocketSession { public void delegateMessages(String[] messages) { for (String message : messages) { - this.handler.handleTextMessage(new TextMessage(message), this); + this.handler.handleMessage(this, new TextMessage(message)); } } public void delegateError(Throwable ex) { - this.handler.handleTransportError(ex, this); + this.handler.handleTransportError(this, ex); } /** @@ -160,7 +160,7 @@ public abstract class AbstractSockJsSession implements WebSocketSession { } finally { this.state = State.CLOSED; - this.handler.afterConnectionClosed(status, this); + this.handler.afterConnectionClosed(this, status); } } } @@ -190,7 +190,7 @@ public abstract class AbstractSockJsSession implements WebSocketSession { } finally { this.state = State.CLOSED; - this.handler.afterConnectionClosed(status, this); + this.handler.afterConnectionClosed(this, status); } } } diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/SockJsSessionFactory.java b/spring-websocket/src/main/java/org/springframework/sockjs/SockJsSessionFactory.java index d9be6247914..2f8f66c3bbc 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/SockJsSessionFactory.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/SockJsSessionFactory.java @@ -35,6 +35,6 @@ public interface SockJsSessionFactory{ * @param handler the underlying {@link WebSocketHandler} * @return a new non-null session */ - S createSession(String sessionId, HandlerProvider handler); + S createSession(String sessionId, HandlerProvider> handler); } diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/AbstractServerSockJsSession.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/AbstractServerSockJsSession.java index 7f2e7bbeea5..3ba7ae422c8 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/AbstractServerSockJsSession.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/AbstractServerSockJsSession.java @@ -45,7 +45,7 @@ public abstract class AbstractServerSockJsSession extends AbstractSockJsSession public AbstractServerSockJsSession(String sessionId, SockJsConfiguration config, - HandlerProvider handler) { + HandlerProvider> handler) { super(sessionId, handler); this.sockJsConfig = config; diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/AbstractSockJsService.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/AbstractSockJsService.java index 8e8999a0496..dddd2c73208 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/AbstractSockJsService.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/AbstractSockJsService.java @@ -200,7 +200,7 @@ public abstract class AbstractSockJsService implements SockJsService, SockJsConf * @throws Exception */ public final void handleRequest(ServerHttpRequest request, ServerHttpResponse response, - String sockJsPath, HandlerProvider handler) + String sockJsPath, HandlerProvider> handler) throws IOException, TransportErrorException { logger.debug(request.getMethod() + " [" + sockJsPath + "]"); @@ -255,10 +255,10 @@ public abstract class AbstractSockJsService implements SockJsService, SockJsConf } protected abstract void handleRawWebSocketRequest(ServerHttpRequest request, ServerHttpResponse response, - HandlerProvider handler) throws IOException; + HandlerProvider> handler) throws IOException; protected abstract void handleTransportRequest(ServerHttpRequest request, ServerHttpResponse response, - String sessionId, TransportType transportType, HandlerProvider handler) + String sessionId, TransportType transportType, HandlerProvider> handler) throws IOException, TransportErrorException; diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/SockJsService.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/SockJsService.java index 46d357cc6a3..0e2a91cbf46 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/SockJsService.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/SockJsService.java @@ -30,6 +30,6 @@ import org.springframework.websocket.WebSocketHandler; public interface SockJsService { void handleRequest(ServerHttpRequest request, ServerHttpResponse response, String sockJsPath, - HandlerProvider handler) throws IOException, TransportErrorException; + HandlerProvider> handler) throws IOException, TransportErrorException; } diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/TransportHandler.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/TransportHandler.java index beac1aa1a3a..80d95fbd912 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/TransportHandler.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/TransportHandler.java @@ -31,6 +31,6 @@ public interface TransportHandler { TransportType getTransportType(); void handleRequest(ServerHttpRequest request, ServerHttpResponse response, - HandlerProvider handler, AbstractSockJsSession session) throws TransportErrorException; + HandlerProvider> handler, AbstractSockJsSession session) throws TransportErrorException; } diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/support/DefaultSockJsService.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/support/DefaultSockJsService.java index a0d61f79e2e..28181ef124b 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/support/DefaultSockJsService.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/support/DefaultSockJsService.java @@ -143,7 +143,7 @@ public class DefaultSockJsService extends AbstractSockJsService { @Override protected void handleRawWebSocketRequest(ServerHttpRequest request, ServerHttpResponse response, - HandlerProvider handler) throws IOException { + HandlerProvider> handler) throws IOException { if (isWebSocketEnabled()) { TransportHandler transportHandler = this.transportHandlers.get(TransportType.WEBSOCKET); @@ -160,7 +160,7 @@ public class DefaultSockJsService extends AbstractSockJsService { @Override protected void handleTransportRequest(ServerHttpRequest request, ServerHttpResponse response, - String sessionId, TransportType transportType, HandlerProvider handler) + String sessionId, TransportType transportType, HandlerProvider> handler) throws IOException, TransportErrorException { TransportHandler transportHandler = this.transportHandlers.get(transportType); @@ -210,7 +210,7 @@ public class DefaultSockJsService extends AbstractSockJsService { transportHandler.handleRequest(request, response, handler, session); } - public AbstractSockJsSession getSockJsSession(String sessionId, HandlerProvider handler, + public AbstractSockJsSession getSockJsSession(String sessionId, HandlerProvider> handler, TransportHandler transportHandler) { AbstractSockJsSession session = this.sessions.get(sessionId); diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/support/SockJsHttpRequestHandler.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/support/SockJsHttpRequestHandler.java index cb583622d20..a90de740144 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/support/SockJsHttpRequestHandler.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/support/SockJsHttpRequestHandler.java @@ -45,7 +45,7 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler { private final SockJsService sockJsService; - private final HandlerProvider handlerProvider; + private final HandlerProvider> handlerProvider; private final UrlPathHelper urlPathHelper = new UrlPathHelper(); @@ -65,7 +65,7 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler { this.prefix = prefix; this.sockJsService = sockJsService; - this.handlerProvider = new SimpleHandlerProvider(handler); + this.handlerProvider = new SimpleHandlerProvider>(handler); } /** @@ -76,7 +76,7 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler { * Servlet container this is the path within the current servlet mapping. */ public SockJsHttpRequestHandler(String prefix, SockJsService sockJsService, - HandlerProvider handlerProvider) { + HandlerProvider> handlerProvider) { Assert.hasText(prefix, "prefix is required"); Assert.notNull(sockJsService, "sockJsService is required"); diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpReceivingTransportHandler.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpReceivingTransportHandler.java index 0f1fd0d2465..6da6af510ea 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpReceivingTransportHandler.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpReceivingTransportHandler.java @@ -55,7 +55,7 @@ public abstract class AbstractHttpReceivingTransportHandler implements Transport @Override public final void handleRequest(ServerHttpRequest request, ServerHttpResponse response, - HandlerProvider webSocketHandler, AbstractSockJsSession session) + HandlerProvider> webSocketHandler, AbstractSockJsSession session) throws TransportErrorException { if (session == null) { diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpSendingTransportHandler.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpSendingTransportHandler.java index ac53c77f58c..f7bfcfeeeb5 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpSendingTransportHandler.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpSendingTransportHandler.java @@ -58,7 +58,7 @@ public abstract class AbstractHttpSendingTransportHandler @Override public final void handleRequest(ServerHttpRequest request, ServerHttpResponse response, - HandlerProvider webSocketHandler, AbstractSockJsSession session) + HandlerProvider> webSocketHandler, AbstractSockJsSession session) throws TransportErrorException { // Set content type before writing diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpServerSockJsSession.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpServerSockJsSession.java index 0492fee3156..0a59625bcda 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpServerSockJsSession.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/AbstractHttpServerSockJsSession.java @@ -51,7 +51,7 @@ public abstract class AbstractHttpServerSockJsSession extends AbstractServerSock public AbstractHttpServerSockJsSession(String sessionId, SockJsConfiguration sockJsConfig, - HandlerProvider handler) { + HandlerProvider> handler) { super(sessionId, sockJsConfig, handler); } diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/EventSourceTransportHandler.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/EventSourceTransportHandler.java index 8fb5a0313c0..ec59fa8a260 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/EventSourceTransportHandler.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/EventSourceTransportHandler.java @@ -47,7 +47,7 @@ public class EventSourceTransportHandler extends AbstractHttpSendingTransportHan } @Override - public StreamingServerSockJsSession createSession(String sessionId, HandlerProvider handler) { + public StreamingServerSockJsSession createSession(String sessionId, HandlerProvider> handler) { Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration"); return new StreamingServerSockJsSession(sessionId, getSockJsConfig(), handler) { @Override diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/HtmlFileTransportHandler.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/HtmlFileTransportHandler.java index 3075aade2be..e2fda86dbcb 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/HtmlFileTransportHandler.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/HtmlFileTransportHandler.java @@ -81,7 +81,7 @@ public class HtmlFileTransportHandler extends AbstractHttpSendingTransportHandle } @Override - public StreamingServerSockJsSession createSession(String sessionId, HandlerProvider handler) { + public StreamingServerSockJsSession createSession(String sessionId, HandlerProvider> handler) { Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration"); return new StreamingServerSockJsSession(sessionId, getSockJsConfig(), handler) { diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/JsonpPollingTransportHandler.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/JsonpPollingTransportHandler.java index cc036453546..8fed9533c62 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/JsonpPollingTransportHandler.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/JsonpPollingTransportHandler.java @@ -51,7 +51,7 @@ public class JsonpPollingTransportHandler extends AbstractHttpSendingTransportHa } @Override - public PollingServerSockJsSession createSession(String sessionId, HandlerProvider handler) { + public PollingServerSockJsSession createSession(String sessionId, HandlerProvider> handler) { Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration"); return new PollingServerSockJsSession(sessionId, getSockJsConfig(), handler); } diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/PollingServerSockJsSession.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/PollingServerSockJsSession.java index 743c3694875..89aa292c14c 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/PollingServerSockJsSession.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/PollingServerSockJsSession.java @@ -26,7 +26,7 @@ import org.springframework.websocket.WebSocketHandler; public class PollingServerSockJsSession extends AbstractHttpServerSockJsSession { public PollingServerSockJsSession(String sessionId, SockJsConfiguration sockJsConfig, - HandlerProvider handler) { + HandlerProvider> handler) { super(sessionId, sockJsConfig, handler); } diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/SockJsWebSocketHandler.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/SockJsWebSocketHandler.java index 95cb4a05227..b8da4c33f0d 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/SockJsWebSocketHandler.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/SockJsWebSocketHandler.java @@ -27,9 +27,9 @@ import org.springframework.util.StringUtils; import org.springframework.websocket.CloseStatus; import org.springframework.websocket.HandlerProvider; import org.springframework.websocket.TextMessage; -import org.springframework.websocket.TextWebSocketHandlerAdapter; import org.springframework.websocket.WebSocketHandler; import org.springframework.websocket.WebSocketSession; +import org.springframework.websocket.adapter.TextWebSocketHandlerAdapter; import com.fasterxml.jackson.databind.ObjectMapper; @@ -45,7 +45,7 @@ public class SockJsWebSocketHandler extends TextWebSocketHandlerAdapter { private final SockJsConfiguration sockJsConfig; - private final HandlerProvider handlerProvider; + private final HandlerProvider> handlerProvider; private WebSocketServerSockJsSession sockJsSession; @@ -55,7 +55,7 @@ public class SockJsWebSocketHandler extends TextWebSocketHandlerAdapter { private final ObjectMapper objectMapper = new ObjectMapper(); - public SockJsWebSocketHandler(SockJsConfiguration config, HandlerProvider handlerProvider) { + public SockJsWebSocketHandler(SockJsConfiguration config, HandlerProvider> handlerProvider) { Assert.notNull(config, "sockJsConfig is required"); Assert.notNull(handlerProvider, "handlerProvider is required"); this.sockJsConfig = config; @@ -74,17 +74,17 @@ public class SockJsWebSocketHandler extends TextWebSocketHandlerAdapter { } @Override - public void handleTextMessage(TextMessage message, WebSocketSession wsSession) { + public void handleMessage(WebSocketSession wsSession, TextMessage message) { this.sockJsSession.handleMessage(message, wsSession); } @Override - public void afterConnectionClosed(CloseStatus status, WebSocketSession wsSession) { + public void afterConnectionClosed(WebSocketSession wsSession, CloseStatus status) { this.sockJsSession.delegateConnectionClosed(status); } @Override - public void handleTransportError(Throwable exception, WebSocketSession webSocketSession) { + public void handleTransportError(WebSocketSession webSocketSession, Throwable exception) { this.sockJsSession.delegateError(exception); } diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/StreamingServerSockJsSession.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/StreamingServerSockJsSession.java index 506985ba734..a5352e7f1ca 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/StreamingServerSockJsSession.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/StreamingServerSockJsSession.java @@ -33,7 +33,7 @@ public class StreamingServerSockJsSession extends AbstractHttpServerSockJsSessio public StreamingServerSockJsSession(String sessionId, SockJsConfiguration sockJsConfig, - HandlerProvider handler) { + HandlerProvider> handler) { super(sessionId, sockJsConfig, handler); } diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/WebSocketTransportHandler.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/WebSocketTransportHandler.java index 8f615c913dc..6d1b83955cd 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/WebSocketTransportHandler.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/WebSocketTransportHandler.java @@ -65,11 +65,11 @@ public class WebSocketTransportHandler implements ConfigurableTransportHandler, @Override public void handleRequest(ServerHttpRequest request, ServerHttpResponse response, - HandlerProvider handler, AbstractSockJsSession session) throws TransportErrorException { + HandlerProvider> handler, AbstractSockJsSession session) throws TransportErrorException { try { - WebSocketHandler sockJsWrapper = new SockJsWebSocketHandler(this.sockJsConfig, handler); - this.handshakeHandler.doHandshake(request, response, new SimpleHandlerProvider(sockJsWrapper)); + WebSocketHandler sockJsWrapper = new SockJsWebSocketHandler(this.sockJsConfig, handler); + this.handshakeHandler.doHandshake(request, response, new SimpleHandlerProvider>(sockJsWrapper)); } catch (Throwable t) { throw new TransportErrorException("Failed to start handshake request", t, session.getId()); @@ -80,7 +80,7 @@ public class WebSocketTransportHandler implements ConfigurableTransportHandler, @Override public boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response, - HandlerProvider handler) throws IOException { + HandlerProvider> handler) throws IOException { return this.handshakeHandler.doHandshake(request, response, handler); } diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/XhrPollingTransportHandler.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/XhrPollingTransportHandler.java index 06a6aaf37d8..7c7709e0c24 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/XhrPollingTransportHandler.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/XhrPollingTransportHandler.java @@ -51,7 +51,7 @@ public class XhrPollingTransportHandler extends AbstractHttpSendingTransportHand return new DefaultFrameFormat("%s\n"); } - public PollingServerSockJsSession createSession(String sessionId, HandlerProvider handler) { + public PollingServerSockJsSession createSession(String sessionId, HandlerProvider> handler) { Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration"); return new PollingServerSockJsSession(sessionId, getSockJsConfig(), handler); } diff --git a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/XhrStreamingTransportHandler.java b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/XhrStreamingTransportHandler.java index 9e6c7457a48..ef31f696284 100644 --- a/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/XhrStreamingTransportHandler.java +++ b/spring-websocket/src/main/java/org/springframework/sockjs/server/transport/XhrStreamingTransportHandler.java @@ -48,7 +48,7 @@ public class XhrStreamingTransportHandler extends AbstractHttpSendingTransportHa } @Override - public StreamingServerSockJsSession createSession(String sessionId, HandlerProvider handler) { + public StreamingServerSockJsSession createSession(String sessionId, HandlerProvider> handler) { Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration"); return new StreamingServerSockJsSession(sessionId, getSockJsConfig(), handler) { diff --git a/spring-websocket/src/main/java/org/springframework/websocket/BinaryMessage.java b/spring-websocket/src/main/java/org/springframework/websocket/BinaryMessage.java index 8bc0e420076..90d3efd6910 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/BinaryMessage.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/BinaryMessage.java @@ -19,8 +19,6 @@ import java.io.ByteArrayInputStream; import java.io.InputStream; import java.nio.ByteBuffer; -import org.springframework.util.Assert; - /** * A {@link WebSocketMessage} that contains a binary {@link ByteBuffer} payload. diff --git a/spring-websocket/src/main/java/org/springframework/websocket/BinaryWebSocketHandlerAdapter.java b/spring-websocket/src/main/java/org/springframework/websocket/BinaryWebSocketHandlerAdapter.java deleted file mode 100644 index acfeeab6d2e..00000000000 --- a/spring-websocket/src/main/java/org/springframework/websocket/BinaryWebSocketHandlerAdapter.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.websocket; - -import java.io.IOException; - - -/** - * - * @author rossen - */ -public class BinaryWebSocketHandlerAdapter extends WebSocketHandlerAdapter { - - @Override - public void handleTextMessage(TextMessage message, WebSocketSession session) { - try { - session.close(CloseStatus.NOT_ACCEPTABLE.withReason("Text messages not supported")); - } - catch (IOException e) { - // ignore - } - } - -} diff --git a/spring-websocket/src/main/java/org/springframework/websocket/TextWebSocketHandlerAdapter.java b/spring-websocket/src/main/java/org/springframework/websocket/TextWebSocketHandlerAdapter.java deleted file mode 100644 index 69941bfa14a..00000000000 --- a/spring-websocket/src/main/java/org/springframework/websocket/TextWebSocketHandlerAdapter.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2002-2013 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.websocket; - -import java.io.IOException; - - -/** - * - * @author Rossen Stoyanchev - * @since 4.0 - */ -public class TextWebSocketHandlerAdapter extends WebSocketHandlerAdapter { - - @Override - public void handleBinaryMessage(BinaryMessage message, WebSocketSession session) { - try { - session.close(CloseStatus.NOT_ACCEPTABLE.withReason("Binary messages not supported")); - } - catch (IOException e) { - // ignore - } - } - -} diff --git a/spring-websocket/src/main/java/org/springframework/websocket/WebSocketHandler.java b/spring-websocket/src/main/java/org/springframework/websocket/WebSocketHandler.java index 5984d49ae0c..3b0b9476f93 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/WebSocketHandler.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/WebSocketHandler.java @@ -19,10 +19,14 @@ package org.springframework.websocket; /** * A handler for WebSocket sessions. * + * @param The type of message being handled {@link TextMessage}, {@link BinaryMessage} + * (or {@link WebSocketMessage} for both). + * * @author Rossen Stoyanchev + * @author Phillip Webb * @since 4.0 */ -public interface WebSocketHandler { +public interface WebSocketHandler> { /** * A new WebSocket connection has been opened and is ready to be used. @@ -30,23 +34,18 @@ public interface WebSocketHandler { void afterConnectionEstablished(WebSocketSession session); /** - * Handle an incoming text message. + * Handle an incoming WebSocket message. */ - void handleTextMessage(TextMessage message, WebSocketSession session); + void handleMessage(WebSocketSession session, T message); /** - * Handle an incoming binary message. + * Handle an error from the underlying WebSocket message transport. */ - void handleBinaryMessage(BinaryMessage message, WebSocketSession session); - - /** - * TODO - */ - void handleTransportError(Throwable exception, WebSocketSession session); + void handleTransportError(WebSocketSession session, Throwable exception); /** * A WebSocket connection has been closed. */ - void afterConnectionClosed(CloseStatus closeStatus, WebSocketSession session); + void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus); } diff --git a/spring-websocket/src/main/java/org/springframework/websocket/WebSocketMessage.java b/spring-websocket/src/main/java/org/springframework/websocket/WebSocketMessage.java index 61d4f11b7c7..a5a06824b0d 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/WebSocketMessage.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/WebSocketMessage.java @@ -20,9 +20,9 @@ import org.springframework.util.Assert; import org.springframework.util.ObjectUtils; /** - * A message that can be sent or received over a WebSocket connection. A WebSocket - * message must be either a {@link BinaryMessage} or a {@link TextMessage} depending - * on the payload. No further subclasses are supported. + * A message that can be handled or sent during a WebSocket interaction. There are only + * two sub-classes {@link BinaryMessage} or a {@link TextMessage} with no further + * sub-classing expected. * * @author Rossen Stoyanchev * @since 4.0 @@ -35,7 +35,7 @@ public abstract class WebSocketMessage { /** - * Create a new {@link WebSocketMessage} instance. + * Create a new {@link WebSocketMessage} instance with the given payload. * @param payload a non-null payload */ WebSocketMessage(T payload) { diff --git a/spring-websocket/src/main/java/org/springframework/websocket/adapter/AbstractWebSocketSesssionAdapter.java b/spring-websocket/src/main/java/org/springframework/websocket/adapter/AbstractWebSocketSesssionAdapter.java new file mode 100644 index 00000000000..122f2264c53 --- /dev/null +++ b/spring-websocket/src/main/java/org/springframework/websocket/adapter/AbstractWebSocketSesssionAdapter.java @@ -0,0 +1,83 @@ +/* + * Copyright 2002-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.websocket.adapter; + +import java.io.IOException; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.springframework.util.Assert; +import org.springframework.websocket.BinaryMessage; +import org.springframework.websocket.CloseStatus; +import org.springframework.websocket.TextMessage; +import org.springframework.websocket.WebSocketMessage; +import org.springframework.websocket.WebSocketSession; + + +/** + * An base class for implementations adapting {@link WebSocketSession}. + * + * @author Rossen Stoyanchev + * @since 4.0 + */ +public abstract class AbstractWebSocketSesssionAdapter implements WebSocketSession { + + protected final Log logger = LogFactory.getLog(getClass()); + + + @Override + public final void sendMessage(WebSocketMessage message) throws IOException { + if (logger.isTraceEnabled()) { + logger.trace("Sending " + message + ", " + this); + } + Assert.isTrue(isOpen(), "Cannot send message after connection closed."); + if (message instanceof TextMessage) { + sendTextMessage((TextMessage) message); + } + else if (message instanceof BinaryMessage) { + sendBinaryMessage((BinaryMessage) message); + } + else { + throw new IllegalStateException("Unexpected WebSocketMessage type: " + message); + } + } + + protected abstract void sendTextMessage(TextMessage message) throws IOException ; + + protected abstract void sendBinaryMessage(BinaryMessage message) throws IOException ; + + @Override + public void close() throws IOException { + close(CloseStatus.NORMAL); + } + + @Override + public final void close(CloseStatus status) throws IOException { + if (logger.isDebugEnabled()) { + logger.debug("Closing " + this); + } + closeInternal(status); + } + + protected abstract void closeInternal(CloseStatus status) throws IOException; + + @Override + public String toString() { + return "WebSocket session id=" + getId(); + } + +} diff --git a/spring-websocket/src/main/java/org/springframework/websocket/adapter/BinaryWebSocketHandlerAdapter.java b/spring-websocket/src/main/java/org/springframework/websocket/adapter/BinaryWebSocketHandlerAdapter.java new file mode 100644 index 00000000000..d136dc9012a --- /dev/null +++ b/spring-websocket/src/main/java/org/springframework/websocket/adapter/BinaryWebSocketHandlerAdapter.java @@ -0,0 +1,50 @@ +/* + * Copyright 2002-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.websocket.adapter; + +import org.springframework.websocket.BinaryMessage; +import org.springframework.websocket.CloseStatus; +import org.springframework.websocket.WebSocketHandler; +import org.springframework.websocket.WebSocketSession; + + +/** + * A {@link WebSocketHandler} for binary messages with empty methods. + * + * @author Rossen Stoyanchev + * @author Phillip Webb + * @since 4.0 + */ +public class BinaryWebSocketHandlerAdapter implements WebSocketHandler { + + @Override + public void afterConnectionEstablished(WebSocketSession session) { + } + + @Override + public void handleMessage(WebSocketSession session, BinaryMessage message) { + } + + @Override + public void handleTransportError(WebSocketSession session, Throwable exception) { + } + + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { + } + +} diff --git a/spring-websocket/src/main/java/org/springframework/websocket/adapter/JettyWebSocketListenerAdapter.java b/spring-websocket/src/main/java/org/springframework/websocket/adapter/JettyWebSocketListenerAdapter.java index 2ec1ec6f569..ccfe4b4048a 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/adapter/JettyWebSocketListenerAdapter.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/adapter/JettyWebSocketListenerAdapter.java @@ -26,6 +26,7 @@ import org.springframework.websocket.CloseStatus; import org.springframework.websocket.HandlerProvider; import org.springframework.websocket.TextMessage; import org.springframework.websocket.WebSocketHandler; +import org.springframework.websocket.WebSocketMessage; import org.springframework.websocket.WebSocketSession; /** @@ -38,12 +39,12 @@ public class JettyWebSocketListenerAdapter implements WebSocketListener { private static Log logger = LogFactory.getLog(JettyWebSocketListenerAdapter.class); - private final WebSocketHandler handler; + private final WebSocketHandler> handler; private WebSocketSession wsSession; - public JettyWebSocketListenerAdapter(HandlerProvider provider) { + public JettyWebSocketListenerAdapter(HandlerProvider> provider) { Assert.notNull(provider, "provider is required"); this.handler = new WebSocketHandlerInvoker(provider).setLogger(logger); } @@ -58,23 +59,23 @@ public class JettyWebSocketListenerAdapter implements WebSocketListener { @Override public void onWebSocketClose(int statusCode, String reason) { CloseStatus closeStatus = new CloseStatus(statusCode, reason); - this.handler.afterConnectionClosed(closeStatus, this.wsSession); + this.handler.afterConnectionClosed(this.wsSession, closeStatus); } @Override public void onWebSocketText(String payload) { TextMessage message = new TextMessage(payload); - this.handler.handleTextMessage(message, this.wsSession); + this.handler.handleMessage(this.wsSession, message); } @Override public void onWebSocketBinary(byte[] payload, int offset, int len) { BinaryMessage message = new BinaryMessage(payload, offset, len); - this.handler.handleBinaryMessage(message, this.wsSession); + this.handler.handleMessage(this.wsSession, message); } @Override public void onWebSocketError(Throwable cause) { - this.handler.handleTransportError(cause, this.wsSession); + this.handler.handleTransportError(this.wsSession, cause); } } diff --git a/spring-websocket/src/main/java/org/springframework/websocket/adapter/JettyWebSocketSessionAdapter.java b/spring-websocket/src/main/java/org/springframework/websocket/adapter/JettyWebSocketSessionAdapter.java index ef23f92427d..c48f1b7db3f 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/adapter/JettyWebSocketSessionAdapter.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/adapter/JettyWebSocketSessionAdapter.java @@ -24,7 +24,6 @@ import org.springframework.util.ObjectUtils; import org.springframework.websocket.BinaryMessage; import org.springframework.websocket.CloseStatus; import org.springframework.websocket.TextMessage; -import org.springframework.websocket.WebSocketMessage; import org.springframework.websocket.WebSocketSession; @@ -34,7 +33,7 @@ import org.springframework.websocket.WebSocketSession; * @author Phillip Webb * @since 4.0 */ -public class JettyWebSocketSessionAdapter implements WebSocketSession { +public class JettyWebSocketSessionAdapter extends AbstractWebSocketSesssionAdapter { private Session session; @@ -65,33 +64,17 @@ public class JettyWebSocketSessionAdapter implements WebSocketSession { } @Override - public void sendMessage(WebSocketMessage message) throws IOException { - if (message instanceof BinaryMessage) { - sendMessage((BinaryMessage) message); - } - else if (message instanceof TextMessage) { - sendMessage((TextMessage) message); - } - else { - throw new IllegalArgumentException("Unsupported message type"); - } - } - - private void sendMessage(BinaryMessage message) throws IOException { - this.session.getRemote().sendBytes(message.getPayload()); - } - - private void sendMessage(TextMessage message) throws IOException { + protected void sendTextMessage(TextMessage message) throws IOException { this.session.getRemote().sendString(message.getPayload()); } @Override - public void close() throws IOException { - this.session.close(); + protected void sendBinaryMessage(BinaryMessage message) throws IOException { + this.session.getRemote().sendBytes(message.getPayload()); } @Override - public void close(CloseStatus status) throws IOException { + protected void closeInternal(CloseStatus status) throws IOException { this.session.close(status.getCode(), status.getReason()); } diff --git a/spring-websocket/src/main/java/org/springframework/websocket/adapter/StandardEndpointAdapter.java b/spring-websocket/src/main/java/org/springframework/websocket/adapter/StandardEndpointAdapter.java index 3ce78ab01f9..a0f06d0c205 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/adapter/StandardEndpointAdapter.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/adapter/StandardEndpointAdapter.java @@ -32,6 +32,7 @@ import org.springframework.websocket.HandlerProvider; import org.springframework.websocket.PartialMessageHandler; import org.springframework.websocket.TextMessage; import org.springframework.websocket.WebSocketHandler; +import org.springframework.websocket.WebSocketMessage; import org.springframework.websocket.WebSocketSession; @@ -45,7 +46,7 @@ public class StandardEndpointAdapter extends Endpoint { private static Log logger = LogFactory.getLog(StandardEndpointAdapter.class); - private final WebSocketHandler handler; + private final WebSocketHandler> handler; private final Class handlerClass; @@ -53,7 +54,7 @@ public class StandardEndpointAdapter extends Endpoint { - public StandardEndpointAdapter(HandlerProvider provider) { + public StandardEndpointAdapter(HandlerProvider> provider) { Assert.notNull(provider, "provider is required"); this.handler = new WebSocketHandlerInvoker(provider).setLogger(logger); this.handlerClass= provider.getHandlerType(); @@ -69,15 +70,8 @@ public class StandardEndpointAdapter extends Endpoint { handleTextMessage(session, message); } }); - if (PartialMessageHandler.class.isAssignableFrom(this.handlerClass)) { - session.addMessageHandler(new MessageHandler.Partial() { - @Override - public void onMessage(ByteBuffer messagePart, boolean isLast) { - handleBinaryMessage(session, messagePart, isLast); - } - }); - } - else { + + if (!PartialMessageHandler.class.isAssignableFrom(this.handlerClass)) { session.addMessageHandler(new MessageHandler.Whole() { @Override public void onMessage(ByteBuffer message) { @@ -85,30 +79,38 @@ public class StandardEndpointAdapter extends Endpoint { } }); } + else { + session.addMessageHandler(new MessageHandler.Partial() { + @Override + public void onMessage(ByteBuffer messagePart, boolean isLast) { + handleBinaryMessage(session, messagePart, isLast); + } + }); + } this.wsSession = new StandardWebSocketSessionAdapter(session); this.handler.afterConnectionEstablished(this.wsSession); } private void handleTextMessage(javax.websocket.Session session, String payload) { - TextMessage message = new TextMessage(payload); - this.handler.handleTextMessage(message, this.wsSession); + TextMessage textMessage = new TextMessage(payload); + this.handler.handleMessage(this.wsSession, textMessage); } private void handleBinaryMessage(javax.websocket.Session session, ByteBuffer payload, boolean isLast) { - BinaryMessage message = new BinaryMessage(payload, isLast); - this.handler.handleBinaryMessage(message, this.wsSession); + BinaryMessage binaryMessage = new BinaryMessage(payload, isLast); + this.handler.handleMessage(this.wsSession, binaryMessage); } @Override public void onClose(javax.websocket.Session session, CloseReason reason) { CloseStatus closeStatus = new CloseStatus(reason.getCloseCode().getCode(), reason.getReasonPhrase()); - this.handler.afterConnectionClosed(closeStatus, this.wsSession); + this.handler.afterConnectionClosed(this.wsSession, closeStatus); } @Override public void onError(javax.websocket.Session session, Throwable exception) { - this.handler.handleTransportError(exception, this.wsSession); + this.handler.handleTransportError(this.wsSession, exception); } } diff --git a/spring-websocket/src/main/java/org/springframework/websocket/adapter/StandardWebSocketSessionAdapter.java b/spring-websocket/src/main/java/org/springframework/websocket/adapter/StandardWebSocketSessionAdapter.java index 30bc063baf2..811ebd93c59 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/adapter/StandardWebSocketSessionAdapter.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/adapter/StandardWebSocketSessionAdapter.java @@ -21,15 +21,11 @@ import java.net.URI; import javax.websocket.CloseReason; import javax.websocket.CloseReason.CloseCodes; -import javax.websocket.RemoteEndpoint.Basic; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; import org.springframework.util.Assert; import org.springframework.websocket.BinaryMessage; import org.springframework.websocket.CloseStatus; import org.springframework.websocket.TextMessage; -import org.springframework.websocket.WebSocketMessage; import org.springframework.websocket.WebSocketSession; /** @@ -39,9 +35,7 @@ import org.springframework.websocket.WebSocketSession; * @author Rossen Stoyanchev * @since 4.0 */ -public class StandardWebSocketSessionAdapter implements WebSocketSession { - - private static Log logger = LogFactory.getLog(StandardWebSocketSessionAdapter.class); +public class StandardWebSocketSessionAdapter extends AbstractWebSocketSesssionAdapter { private final javax.websocket.Session session; @@ -73,39 +67,18 @@ public class StandardWebSocketSessionAdapter implements WebSocketSession { } @Override - public void sendMessage(WebSocketMessage message) throws IOException { - if (logger.isTraceEnabled()) { - logger.trace("Sending: " + message + ", " + this); - } - Assert.isTrue(isOpen(), "Cannot send message after connection closed."); - Basic remote = this.session.getBasicRemote(); - if (message instanceof TextMessage) { - remote.sendText(((TextMessage) message).getPayload()); - } - else if (message instanceof BinaryMessage) { - remote.sendBinary(((BinaryMessage) message).getPayload()); - } - else { - throw new IllegalStateException("Unexpected WebSocketMessage type: " + message); - } + protected void sendTextMessage(TextMessage message) throws IOException { + this.session.getBasicRemote().sendText(message.getPayload()); } @Override - public void close() throws IOException { - close(CloseStatus.NORMAL); + protected void sendBinaryMessage(BinaryMessage message) throws IOException { + this.session.getBasicRemote().sendBinary(message.getPayload()); } @Override - public void close(CloseStatus status) throws IOException { - if (logger.isDebugEnabled()) { - logger.debug("Closing " + this); - } + protected void closeInternal(CloseStatus status) throws IOException { this.session.close(new CloseReason(CloseCodes.getCloseCode(status.getCode()), status.getReason())); } - @Override - public String toString() { - return "WebSocket session id=" + getId(); - } - } diff --git a/spring-websocket/src/main/java/org/springframework/websocket/WebSocketHandlerAdapter.java b/spring-websocket/src/main/java/org/springframework/websocket/adapter/TextWebSocketHandlerAdapter.java similarity index 54% rename from spring-websocket/src/main/java/org/springframework/websocket/WebSocketHandlerAdapter.java rename to spring-websocket/src/main/java/org/springframework/websocket/adapter/TextWebSocketHandlerAdapter.java index b42f7000f09..6c54f653e80 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/WebSocketHandlerAdapter.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/adapter/TextWebSocketHandlerAdapter.java @@ -14,36 +14,37 @@ * limitations under the License. */ -package org.springframework.websocket; +package org.springframework.websocket.adapter; + +import org.springframework.websocket.CloseStatus; +import org.springframework.websocket.TextMessage; +import org.springframework.websocket.WebSocketHandler; +import org.springframework.websocket.WebSocketSession; /** - * A {@link WebSocketHandler} with empty methods. + * A {@link WebSocketHandler} for text messages with empty methods. * * @author Rossen Stoyanchev + * @author Phillip Webb * @since 4.0 - * @see WebSocketHandler */ -public class WebSocketHandlerAdapter implements WebSocketHandler { +public class TextWebSocketHandlerAdapter implements WebSocketHandler { @Override public void afterConnectionEstablished(WebSocketSession session) { } @Override - public void afterConnectionClosed(CloseStatus status, WebSocketSession session) { + public void handleMessage(WebSocketSession session, TextMessage message) { } @Override - public void handleTextMessage(TextMessage message, WebSocketSession session) { + public void handleTransportError(WebSocketSession session, Throwable exception) { } @Override - public void handleBinaryMessage(BinaryMessage message, WebSocketSession session) { - } - - @Override - public void handleTransportError(Throwable exception, WebSocketSession session) { + public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { } } diff --git a/spring-websocket/src/main/java/org/springframework/websocket/adapter/WebSocketHandlerAdapter.java b/spring-websocket/src/main/java/org/springframework/websocket/adapter/WebSocketHandlerAdapter.java new file mode 100644 index 00000000000..8a4c64f630c --- /dev/null +++ b/spring-websocket/src/main/java/org/springframework/websocket/adapter/WebSocketHandlerAdapter.java @@ -0,0 +1,70 @@ +/* + * Copyright 2002-2013 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.websocket.adapter; + +import org.springframework.websocket.BinaryMessage; +import org.springframework.websocket.CloseStatus; +import org.springframework.websocket.TextMessage; +import org.springframework.websocket.WebSocketHandler; +import org.springframework.websocket.WebSocketMessage; +import org.springframework.websocket.WebSocketSession; + + +/** + * A {@link WebSocketHandler} for both text and binary messages with empty methods. + * + * @author Rossen Stoyanchev + * @author Phillip Webb + * @since 4.0 + * + * @see TextWebSocketHandlerAdapter + * @see BinaryWebSocketHandlerAdapter + */ +public class WebSocketHandlerAdapter implements WebSocketHandler> { + + @Override + public void afterConnectionEstablished(WebSocketSession session) { + } + + @Override + public final void handleMessage(WebSocketSession session, WebSocketMessage message) { + if (message instanceof TextMessage) { + handleTextMessage(session, (TextMessage) message); + } + else if (message instanceof BinaryMessage) { + handleBinaryMessage(session, (BinaryMessage) message); + } + else { + throw new IllegalStateException("Unexpected WebSocket message type: " + message); + } + } + + protected void handleTextMessage(WebSocketSession session, TextMessage message) { + } + + protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) { + } + + @Override + public void handleTransportError(WebSocketSession session, Throwable exception) { + } + + @Override + public void afterConnectionClosed(WebSocketSession session, CloseStatus status) { + } + +} diff --git a/spring-websocket/src/main/java/org/springframework/websocket/adapter/WebSocketHandlerInvoker.java b/spring-websocket/src/main/java/org/springframework/websocket/adapter/WebSocketHandlerInvoker.java index 45abc18a524..7e9dce31b0a 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/adapter/WebSocketHandlerInvoker.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/adapter/WebSocketHandlerInvoker.java @@ -20,36 +20,39 @@ import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.springframework.core.GenericTypeResolver; import org.springframework.util.Assert; -import org.springframework.websocket.BinaryMessage; import org.springframework.websocket.CloseStatus; import org.springframework.websocket.HandlerProvider; -import org.springframework.websocket.TextMessage; import org.springframework.websocket.WebSocketHandler; +import org.springframework.websocket.WebSocketMessage; import org.springframework.websocket.WebSocketSession; /** - * A class for managing and delegating to a {@link WebSocketHandler} instance, applying - * initialization and destruction as necessary at the start and end of the WebSocket - * session, ensuring that any unhandled exceptions from its methods are caught and handled - * by closing the session, and also adding uniform logging. + * A class for managing and delegating to a {@link WebSocketHandler} instance, ensuring + * the handler is initialized and destroyed, that any unhandled exceptions from handler + * are caught (and handled by closing the session), as well as adding logging. * * @author Rossen Stoyanchev + * @author Phillip Webb * @since 4.0 */ -public class WebSocketHandlerInvoker implements WebSocketHandler { +public class WebSocketHandlerInvoker implements WebSocketHandler> { private Log logger = LogFactory.getLog(WebSocketHandlerInvoker.class); - private final HandlerProvider handlerProvider; + private final HandlerProvider> handlerProvider; - private WebSocketHandler handler; + private final Class supportedMessageType; + + private WebSocketHandler handler; private final AtomicInteger sessionCount = new AtomicInteger(0); - public WebSocketHandlerInvoker(HandlerProvider handlerProvider) { - this.handlerProvider = handlerProvider; + public WebSocketHandlerInvoker(HandlerProvider> provider) { + this.handlerProvider = provider; + this.supportedMessageType = GenericTypeResolver.resolveTypeArgument(provider.getHandlerType(), WebSocketHandler.class); } public WebSocketHandlerInvoker setLogger(Log logger) { @@ -77,8 +80,10 @@ public class WebSocketHandlerInvoker implements WebSocketHandler { tryCloseWithError(session, ex, null); } - public void tryCloseWithError(WebSocketSession session, Throwable ex, CloseStatus status) { - logger.error("Unhandled error for " + session, ex); + public void tryCloseWithError(WebSocketSession session, Throwable exeption, CloseStatus status) { + if (exeption != null) { + logger.error("Closing due to exception for " + session, exeption); + } if (session.isOpen()) { try { session.close(CloseStatus.SERVER_ERROR); @@ -103,13 +108,18 @@ public class WebSocketHandlerInvoker implements WebSocketHandler { } } + @SuppressWarnings("unchecked") @Override - public void handleTextMessage(TextMessage message, WebSocketSession session) { + public void handleMessage(WebSocketSession session, WebSocketMessage message) { if (logger.isTraceEnabled()) { - logger.trace("Received text message for " + session + ": " + message); + logger.trace("Received " + message + ", " + session); + } + if (!this.supportedMessageType.isAssignableFrom(message.getClass())) { + tryCloseWithError(session, null, CloseStatus.NOT_ACCEPTABLE.withReason("Message type not supported")); + return; } try { - this.handler.handleTextMessage(message, session); + ((WebSocketHandler) this.handler).handleMessage(session, message); } catch (Throwable ex) { tryCloseWithError(session,ex); @@ -117,25 +127,12 @@ public class WebSocketHandlerInvoker implements WebSocketHandler { } @Override - public void handleBinaryMessage(BinaryMessage message, WebSocketSession session) { - if (logger.isTraceEnabled()) { - logger.trace("Received binary message for " + session); - } - try { - this.handler.handleBinaryMessage(message, session); - } - catch (Throwable ex) { - tryCloseWithError(session, ex); - } - } - - @Override - public void handleTransportError(Throwable exception, WebSocketSession session) { + public void handleTransportError(WebSocketSession session, Throwable exception) { if (logger.isDebugEnabled()) { logger.debug("Transport error for " + session, exception); } try { - this.handler.handleTransportError(exception, session); + this.handler.handleTransportError(session, exception); } catch (Throwable ex) { tryCloseWithError(session, ex); @@ -143,12 +140,12 @@ public class WebSocketHandlerInvoker implements WebSocketHandler { } @Override - public void afterConnectionClosed(CloseStatus closeStatus, WebSocketSession session) { + public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) { if (logger.isDebugEnabled()) { logger.debug("Connection closed for " + session + ", " + closeStatus); } try { - this.handler.afterConnectionClosed(closeStatus, session); + this.handler.afterConnectionClosed(session, closeStatus); } catch (Throwable ex) { logger.error("Unhandled error for " + this, ex); diff --git a/spring-websocket/src/main/java/org/springframework/websocket/adapter/package-info.java b/spring-websocket/src/main/java/org/springframework/websocket/adapter/package-info.java index 695869a5ffc..59f29a08a3e 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/adapter/package-info.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/adapter/package-info.java @@ -15,8 +15,9 @@ */ /** - * Adapters for the {@link org.springframework.websocket.WebSocketHandler} and - * {@link org.springframework.websocket.WebSocketSession} contracts. + * Classes adapting Spring's WebSocket API classes to and from various WebSocket + * implementations. Also contains convenient base classes for + * {@link org.springframework.websocket.WebSocketHandler} implementations. */ package org.springframework.websocket.adapter; diff --git a/spring-websocket/src/main/java/org/springframework/websocket/client/WebSocketClient.java b/spring-websocket/src/main/java/org/springframework/websocket/client/WebSocketClient.java index 18260dfd9b6..d77b252a789 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/client/WebSocketClient.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/client/WebSocketClient.java @@ -38,10 +38,10 @@ public interface WebSocketClient { WebSocketSession doHandshake(WebSocketHandler handler, String uriTemplate, Object... uriVariables) throws WebSocketConnectFailureException; - WebSocketSession doHandshake(HandlerProvider handler, + WebSocketSession doHandshake(HandlerProvider> handler, String uriTemplate, Object... uriVariables) throws WebSocketConnectFailureException; - WebSocketSession doHandshake(HandlerProvider handler, HttpHeaders headers, URI uri) + WebSocketSession doHandshake(HandlerProvider> handler, HttpHeaders headers, URI uri) throws WebSocketConnectFailureException; } diff --git a/spring-websocket/src/main/java/org/springframework/websocket/client/WebSocketConnectionManager.java b/spring-websocket/src/main/java/org/springframework/websocket/client/WebSocketConnectionManager.java index 5b84998cafd..d633545cbea 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/client/WebSocketConnectionManager.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/client/WebSocketConnectionManager.java @@ -34,7 +34,7 @@ public class WebSocketConnectionManager extends AbstractWebSocketConnectionManag private final WebSocketClient client; - private final HandlerProvider handlerProvider; + private final HandlerProvider> handlerProvider; private WebSocketSession webSocketSession; @@ -46,11 +46,11 @@ public class WebSocketConnectionManager extends AbstractWebSocketConnectionManag super(uriTemplate, uriVariables); this.client = webSocketClient; - this.handlerProvider = new SimpleHandlerProvider(webSocketHandler); + this.handlerProvider = new SimpleHandlerProvider>(webSocketHandler); } public WebSocketConnectionManager(WebSocketClient webSocketClient, - HandlerProvider handlerProvider, String uriTemplate, Object... uriVariables) { + HandlerProvider> handlerProvider, String uriTemplate, Object... uriVariables) { super(uriTemplate, uriVariables); this.client = webSocketClient; diff --git a/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/StandardWebSocketClient.java b/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/StandardWebSocketClient.java index ca0e103efbb..0b9340807c5 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/StandardWebSocketClient.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/StandardWebSocketClient.java @@ -64,10 +64,10 @@ public class StandardWebSocketClient implements WebSocketClient { public WebSocketSession doHandshake(WebSocketHandler handler, String uriTemplate, Object... uriVariables) throws WebSocketConnectFailureException { - return doHandshake(new SimpleHandlerProvider(handler), uriTemplate, uriVariables); + return doHandshake(new SimpleHandlerProvider>(handler), uriTemplate, uriVariables); } - public WebSocketSession doHandshake(HandlerProvider handler, + public WebSocketSession doHandshake(HandlerProvider> handler, String uriTemplate, Object... uriVariables) throws WebSocketConnectFailureException { URI uri = UriComponentsBuilder.fromUriString(uriTemplate).buildAndExpand(uriVariables).encode().toUri(); @@ -75,7 +75,7 @@ public class StandardWebSocketClient implements WebSocketClient { } @Override - public WebSocketSession doHandshake(HandlerProvider handler, + public WebSocketSession doHandshake(HandlerProvider> handler, final HttpHeaders httpHeaders, URI uri) throws WebSocketConnectFailureException { Endpoint endpoint = new StandardEndpointAdapter(handler); diff --git a/spring-websocket/src/main/java/org/springframework/websocket/server/DefaultHandshakeHandler.java b/spring-websocket/src/main/java/org/springframework/websocket/server/DefaultHandshakeHandler.java index c37ffef466d..46b043fd57b 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/server/DefaultHandshakeHandler.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/server/DefaultHandshakeHandler.java @@ -88,7 +88,7 @@ public class DefaultHandshakeHandler implements HandshakeHandler { @Override public final boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response, - HandlerProvider handler) throws IOException { + HandlerProvider> handler) throws IOException { logger.debug("Starting handshake for " + request.getURI()); diff --git a/spring-websocket/src/main/java/org/springframework/websocket/server/HandshakeHandler.java b/spring-websocket/src/main/java/org/springframework/websocket/server/HandshakeHandler.java index 227b6fefd4b..532dd65501c 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/server/HandshakeHandler.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/server/HandshakeHandler.java @@ -33,6 +33,6 @@ public interface HandshakeHandler { boolean doHandshake(ServerHttpRequest request, ServerHttpResponse response, - HandlerProvider handler) throws IOException; + HandlerProvider> handler) throws IOException; } diff --git a/spring-websocket/src/main/java/org/springframework/websocket/server/RequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/websocket/server/RequestUpgradeStrategy.java index 9af17b4fff1..773d5863f7d 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/server/RequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/server/RequestUpgradeStrategy.java @@ -44,7 +44,7 @@ public interface RequestUpgradeStrategy { * @param handler the handler for WebSocket messages */ void upgrade(ServerHttpRequest request, ServerHttpResponse response, String selectedProtocol, - HandlerProvider handlerProvider) throws IOException; + HandlerProvider> handlerProvider) throws IOException; // FIXME how to indicate failure to upgrade? } diff --git a/spring-websocket/src/main/java/org/springframework/websocket/server/support/AbstractEndpointUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/websocket/server/support/AbstractEndpointUpgradeStrategy.java index e27ca8b66e1..cd34bfdfc72 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/server/support/AbstractEndpointUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/server/support/AbstractEndpointUpgradeStrategy.java @@ -43,13 +43,9 @@ public abstract class AbstractEndpointUpgradeStrategy implements RequestUpgradeS @Override public void upgrade(ServerHttpRequest request, ServerHttpResponse response, - String protocol, HandlerProvider handler) throws IOException { + String protocol, HandlerProvider> handler) throws IOException { - upgradeInternal(request, response, protocol, adaptWebSocketHandler(handler)); - } - - protected Endpoint adaptWebSocketHandler(HandlerProvider handler) { - return new StandardEndpointAdapter(handler); + upgradeInternal(request, response, protocol, new StandardEndpointAdapter(handler)); } protected abstract void upgradeInternal(ServerHttpRequest request, ServerHttpResponse response, diff --git a/spring-websocket/src/main/java/org/springframework/websocket/server/support/JettyRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/websocket/server/support/JettyRequestUpgradeStrategy.java index 95e54b34e42..7448e66ac73 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/server/support/JettyRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/server/support/JettyRequestUpgradeStrategy.java @@ -67,8 +67,8 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy { public Object createWebSocket(UpgradeRequest request, UpgradeResponse response) { Assert.isInstanceOf(ServletWebSocketRequest.class, request); ServletWebSocketRequest servletRequest = (ServletWebSocketRequest) request; - HandlerProvider handlerProvider = - (HandlerProvider) servletRequest.getServletAttributes().get( + HandlerProvider> handlerProvider = + (HandlerProvider>) servletRequest.getServletAttributes().get( HANDLER_PROVIDER_ATTR_NAME); return new JettyWebSocketListenerAdapter(handlerProvider); } @@ -89,7 +89,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy { @Override public void upgrade(ServerHttpRequest request, ServerHttpResponse response, - String selectedProtocol, HandlerProvider handlerProvider) throws IOException { + String selectedProtocol, HandlerProvider> handlerProvider) throws IOException { Assert.isInstanceOf(ServletServerHttpRequest.class, request); HttpServletRequest servletRequest = ((ServletServerHttpRequest) request).getServletRequest(); @@ -101,7 +101,7 @@ public class JettyRequestUpgradeStrategy implements RequestUpgradeStrategy { } private void upgrade(HttpServletRequest request, HttpServletResponse response, - String selectedProtocol, final HandlerProvider handlerProvider) throws IOException { + String selectedProtocol, final HandlerProvider> handlerProvider) throws IOException { Assert.state(this.factory.isUpgradeRequest(request, response), "Not a suitable WebSocket upgrade request"); Assert.state(this.factory.acceptWebSocket(request, response), "Unable to accept WebSocket"); diff --git a/spring-websocket/src/main/java/org/springframework/websocket/server/support/WebSocketHttpRequestHandler.java b/spring-websocket/src/main/java/org/springframework/websocket/server/support/WebSocketHttpRequestHandler.java index c5e622726de..6d8edc0c28c 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/server/support/WebSocketHttpRequestHandler.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/server/support/WebSocketHttpRequestHandler.java @@ -45,18 +45,18 @@ public class WebSocketHttpRequestHandler implements HttpRequestHandler { private final HandshakeHandler handshakeHandler; - private final HandlerProvider handlerProvider; + private final HandlerProvider> handlerProvider; public WebSocketHttpRequestHandler(WebSocketHandler webSocketHandler) { - this(new SimpleHandlerProvider(webSocketHandler)); + this(new SimpleHandlerProvider>(webSocketHandler)); } - public WebSocketHttpRequestHandler( HandlerProvider handlerProvider) { + public WebSocketHttpRequestHandler( HandlerProvider> handlerProvider) { this(handlerProvider, new DefaultHandshakeHandler()); } - public WebSocketHttpRequestHandler( HandlerProvider handlerProvider, + public WebSocketHttpRequestHandler( HandlerProvider> handlerProvider, HandshakeHandler handshakeHandler) { Assert.notNull(handlerProvider, "handlerProvider is required"); Assert.notNull(handshakeHandler, "handshakeHandler is required");