Polish spring-websocket code
Minor polish to formatting and assertion messages.
This commit is contained in:
parent
2d018e5019
commit
60532cbd1e
|
|
@ -91,8 +91,8 @@ public class DefaultDocumentLoader implements DocumentLoader {
|
|||
factory.setNamespaceAware(namespaceAware);
|
||||
|
||||
if (validationMode != XmlValidationModeDetector.VALIDATION_NONE) {
|
||||
factory.setFeature("http://apache.org/xml/features/validation/schema", false);
|
||||
factory.setValidating(true);
|
||||
|
||||
if (validationMode == XmlValidationModeDetector.VALIDATION_XSD) {
|
||||
// Enforce namespace aware for XSD...
|
||||
factory.setNamespaceAware(true);
|
||||
|
|
|
|||
|
|
@ -13,11 +13,11 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.socket;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link WebSocketMessage} that contains a binary {@link ByteBuffer} payload.
|
||||
*
|
||||
|
|
@ -79,6 +79,7 @@ public final class BinaryMessage extends WebSocketMessage<ByteBuffer> {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns access to the message payload as a byte array. NOTE: the returned array
|
||||
* should be considered read-only and should not be modified.
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.socket;
|
||||
|
||||
import org.eclipse.jetty.websocket.api.StatusCode;
|
||||
|
|
@ -148,8 +149,8 @@ public final class CloseStatus {
|
|||
|
||||
/**
|
||||
* Create a new {@link CloseStatus} instance.
|
||||
* @param code
|
||||
* @param reason
|
||||
* @param code the status code
|
||||
* @param reason the reason
|
||||
*/
|
||||
public CloseStatus(int code, String reason) {
|
||||
Assert.isTrue((code >= 1000 && code < 5000), "Invalid code");
|
||||
|
|
@ -157,6 +158,7 @@ public final class CloseStatus {
|
|||
this.reason = reason;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the status code.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -16,7 +16,6 @@
|
|||
|
||||
package org.springframework.web.socket;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link WebSocketMessage} that contains a textual {@link String} payload.
|
||||
*
|
||||
|
|
@ -25,11 +24,9 @@ package org.springframework.web.socket;
|
|||
*/
|
||||
public final class TextMessage extends WebSocketMessage<String> {
|
||||
|
||||
|
||||
/**
|
||||
* Create a new {@link TextMessage} instance.
|
||||
* @param payload the payload
|
||||
* @param isLast whether this the last part of a message received or transmitted in parts
|
||||
*/
|
||||
public TextMessage(CharSequence payload) {
|
||||
super(payload.toString(), true);
|
||||
|
|
@ -44,6 +41,7 @@ public final class TextMessage extends WebSocketMessage<String> {
|
|||
super(payload.toString(), isLast);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected int getPayloadSize() {
|
||||
return getPayload().length();
|
||||
|
|
|
|||
|
|
@ -19,18 +19,15 @@ package org.springframework.web.socket;
|
|||
/**
|
||||
* A handler for WebSocket messages and lifecycle events.
|
||||
*
|
||||
* <p>
|
||||
* Implementations of this interface are encouraged to handle exceptions locally where it
|
||||
* makes sense or alternatively let the exception bubble up in which case the exception is
|
||||
* logged and the session closed with {@link CloseStatus#SERVER_ERROR SERVER_ERROR(1011)}
|
||||
* by default. The exception handling strategy is provided by
|
||||
* <p>Implementations of this interface are encouraged to handle exceptions locally where
|
||||
* it makes sense or alternatively let the exception bubble up in which case the exception
|
||||
* is logged and the session closed with
|
||||
* {@link CloseStatus#SERVER_ERROR SERVER_ERROR(1011)} by default. The exception handling
|
||||
* strategy is provided by
|
||||
* {@link org.springframework.web.socket.support.ExceptionWebSocketHandlerDecorator
|
||||
* ExceptionWebSocketHandlerDecorator}, which can be customized or replaced by decorating
|
||||
* the {@link WebSocketHandler} with a different decorator.
|
||||
*
|
||||
* @param <T> The type of message being handled {@link TextMessage}, {@link BinaryMessage}
|
||||
* (or {@link WebSocketMessage} for both).
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @author Phillip Webb
|
||||
* @since 4.0
|
||||
|
|
@ -40,7 +37,6 @@ public interface WebSocketHandler {
|
|||
/**
|
||||
* Invoked after WebSocket negotiation has succeeded and the WebSocket connection is
|
||||
* opened and ready for use.
|
||||
*
|
||||
* @throws Exception this method can handle or propagate exceptions; see class-level
|
||||
* Javadoc for details.
|
||||
*/
|
||||
|
|
@ -48,7 +44,6 @@ public interface WebSocketHandler {
|
|||
|
||||
/**
|
||||
* Invoked when a new WebSocket message arrives.
|
||||
*
|
||||
* @throws Exception this method can handle or propagate exceptions; see class-level
|
||||
* Javadoc for details.
|
||||
*/
|
||||
|
|
@ -56,7 +51,6 @@ public interface WebSocketHandler {
|
|||
|
||||
/**
|
||||
* Handle an error from the underlying WebSocket message transport.
|
||||
*
|
||||
* @throws Exception this method can handle or propagate exceptions; see class-level
|
||||
* Javadoc for details.
|
||||
*/
|
||||
|
|
@ -67,7 +61,6 @@ public interface WebSocketHandler {
|
|||
* transport error has occurred. Although the session may technically still be open,
|
||||
* depending on the underlying implementation, sending messages at this point is
|
||||
* discouraged and most likely will not succeed.
|
||||
*
|
||||
* @throws Exception this method can handle or propagate exceptions; see class-level
|
||||
* Javadoc for details.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@ public abstract class WebSocketMessage<T> {
|
|||
this.last = isLast;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Returns the message payload. This will never be {@code null}.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import org.springframework.web.socket.TextMessage;
|
|||
import org.springframework.web.socket.WebSocketMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
|
||||
/**
|
||||
* An abstract base class for implementations of {@link WebSocketSession}.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import org.springframework.web.socket.TextMessage;
|
|||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
|
||||
/**
|
||||
* A convenient base class for {@link WebSocketHandler} implementation that process binary
|
||||
* messages only. Text messages are rejected with {@link CloseStatus#NOT_ACCEPTABLE}. All
|
||||
|
|
@ -35,7 +34,6 @@ import org.springframework.web.socket.WebSocketSession;
|
|||
*/
|
||||
public class BinaryWebSocketHandlerAdapter extends WebSocketHandlerAdapter {
|
||||
|
||||
|
||||
@Override
|
||||
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import java.security.Principal;
|
|||
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
|
||||
/**
|
||||
* A WebSocketSession with configurable properties.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -39,12 +39,12 @@ public class JettyWebSocketListenerAdapter implements WebSocketListener {
|
|||
|
||||
private final WebSocketHandler webSocketHandler;
|
||||
|
||||
private JettyWebSocketSessionAdapter wsSession;
|
||||
private final JettyWebSocketSessionAdapter wsSession;
|
||||
|
||||
|
||||
public JettyWebSocketListenerAdapter(WebSocketHandler webSocketHandler, JettyWebSocketSessionAdapter wsSession) {
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler is required");
|
||||
Assert.notNull(wsSession, "wsSession is required");
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler must not be null");
|
||||
Assert.notNull(wsSession, "wsSession must not be null");
|
||||
this.webSocketHandler = webSocketHandler;
|
||||
this.wsSession = wsSession;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import org.springframework.web.socket.CloseStatus;
|
|||
import org.springframework.web.socket.TextMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
|
||||
/**
|
||||
* Adapts a Jetty {@link org.eclipse.jetty.websocket.api.Session} to
|
||||
* {@link WebSocketSession}.
|
||||
|
|
@ -48,7 +47,7 @@ public class JettyWebSocketSessionAdapter
|
|||
|
||||
@Override
|
||||
public void initSession(Session session) {
|
||||
Assert.notNull(session, "session is required");
|
||||
Assert.notNull(session, "session must not be null");
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
|
|
@ -122,4 +121,4 @@ public class JettyWebSocketSessionAdapter
|
|||
this.session.close(status.getCode(), status.getReason());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ import org.springframework.web.socket.TextMessage;
|
|||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.support.ExceptionWebSocketHandlerDecorator;
|
||||
|
||||
|
||||
/**
|
||||
* Adapts a {@link WebSocketHandler} to a standard {@link Endpoint}.
|
||||
*
|
||||
|
|
@ -49,8 +48,8 @@ public class StandardEndpointAdapter extends Endpoint {
|
|||
|
||||
|
||||
public StandardEndpointAdapter(WebSocketHandler handler, StandardWebSocketSessionAdapter wsSession) {
|
||||
Assert.notNull(handler, "handler is required");
|
||||
Assert.notNull(wsSession, "wsSession is required");
|
||||
Assert.notNull(handler, "handler must not be null");
|
||||
Assert.notNull(wsSession, "wsSession must not be null");
|
||||
this.handler = handler;
|
||||
this.wsSession = wsSession;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class StandardWebSocketSessionAdapter extends AbstractWebSocketSesssionAd
|
|||
|
||||
@Override
|
||||
public void initSession(javax.websocket.Session session) {
|
||||
Assert.notNull(session, "session is required");
|
||||
Assert.notNull(session, "session must not be null");
|
||||
this.session = session;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import org.springframework.web.socket.CloseStatus;
|
|||
import org.springframework.web.socket.WebSocketHandler;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
|
||||
/**
|
||||
* A convenient base class for {@link WebSocketHandler} implementation that process text
|
||||
* messages only. Binary messages are rejected with {@link CloseStatus#NOT_ACCEPTABLE}. All
|
||||
|
|
@ -35,7 +34,6 @@ import org.springframework.web.socket.WebSocketSession;
|
|||
*/
|
||||
public class TextWebSocketHandlerAdapter extends WebSocketHandlerAdapter {
|
||||
|
||||
|
||||
@Override
|
||||
protected void handleBinaryMessage(WebSocketSession session, BinaryMessage message) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import org.springframework.web.socket.WebSocketHandler;
|
|||
import org.springframework.web.socket.WebSocketMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
|
||||
/**
|
||||
* A convenient base class for {@link WebSocketHandler} implementation with empty methods.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -48,18 +48,21 @@ public abstract class ConnectionManagerSupport implements SmartLifecycle {
|
|||
|
||||
private int phase = Integer.MAX_VALUE;
|
||||
|
||||
private TaskExecutor taskExecutor = new SimpleAsyncTaskExecutor("EndpointConnectionManager-");
|
||||
private final TaskExecutor taskExecutor = new SimpleAsyncTaskExecutor("EndpointConnectionManager-");
|
||||
|
||||
private final Object lifecycleMonitor = new Object();
|
||||
|
||||
|
||||
public ConnectionManagerSupport(String uriTemplate, Object... uriVariables) {
|
||||
this.uri = UriComponentsBuilder.fromUriString(uriTemplate).buildAndExpand(uriVariables).encode().toUri();
|
||||
this.uri = UriComponentsBuilder.fromUriString(uriTemplate).buildAndExpand(
|
||||
uriVariables).encode().toUri();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether to auto-connect to the remote endpoint after this connection manager
|
||||
* has been initialized and the Spring context has been refreshed.
|
||||
*
|
||||
* <p>Default is "false".
|
||||
*/
|
||||
public void setAutoStartup(boolean autoStartup) {
|
||||
|
|
@ -111,8 +114,7 @@ public abstract class ConnectionManagerSupport implements SmartLifecycle {
|
|||
}
|
||||
|
||||
/**
|
||||
* Connect to the configured {@link #setDefaultUri(URI) default URI}. If already
|
||||
* connected, the method has no impact.
|
||||
* Start the websocket connection. If already connected, the method has no impact.
|
||||
*/
|
||||
@Override
|
||||
public final void start() {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.socket.client;
|
||||
|
||||
import java.net.URI;
|
||||
|
|
@ -25,15 +26,14 @@ import org.springframework.web.socket.WebSocketSession;
|
|||
* Contract for initiating a WebSocket request. As an alternative considering using the
|
||||
* declarative style {@link WebSocketConnectionManager} that starts a WebSocket connection
|
||||
* to a pre-configured URI when the application starts.
|
||||
*
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*
|
||||
*
|
||||
* @see WebSocketConnectionManager
|
||||
*/
|
||||
public interface WebSocketClient {
|
||||
|
||||
|
||||
WebSocketSession doHandshake(WebSocketHandler webSocketHandler,
|
||||
String uriTemplate, Object... uriVariables) throws WebSocketConnectFailureException;
|
||||
|
||||
|
|
|
|||
|
|
@ -27,7 +27,6 @@ import org.springframework.core.NestedRuntimeException;
|
|||
@SuppressWarnings("serial")
|
||||
public class WebSocketConnectFailureException extends NestedRuntimeException {
|
||||
|
||||
|
||||
public WebSocketConnectFailureException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,10 +57,11 @@ public class WebSocketConnectionManager extends ConnectionManagerSupport {
|
|||
this.syncClientLifecycle = ((client instanceof SmartLifecycle) && !((SmartLifecycle) client).isRunning());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decorate the WebSocketHandler provided to the class constructor.
|
||||
* <p>
|
||||
* By default {@link LoggingWebSocketHandlerDecorator} is added.
|
||||
*
|
||||
* <p>By default {@link LoggingWebSocketHandlerDecorator} is added.
|
||||
*/
|
||||
protected WebSocketHandler decorateWebSocketHandler(WebSocketHandler handler) {
|
||||
return new LoggingWebSocketHandlerDecorator(handler);
|
||||
|
|
@ -88,7 +89,7 @@ public class WebSocketConnectionManager extends ConnectionManagerSupport {
|
|||
@Override
|
||||
public void stopInternal() throws Exception {
|
||||
if (this.syncClientLifecycle) {
|
||||
((SmartLifecycle) client).stop();
|
||||
((SmartLifecycle) this.client).stop();
|
||||
}
|
||||
super.stopInternal();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -61,14 +61,14 @@ public class EndpointConnectionManager extends ConnectionManagerSupport implemen
|
|||
|
||||
public EndpointConnectionManager(Endpoint endpoint, String uriTemplate, Object... uriVariables) {
|
||||
super(uriTemplate, uriVariables);
|
||||
Assert.notNull(endpoint, "endpoint is required");
|
||||
Assert.notNull(endpoint, "endpoint must not be null");
|
||||
this.endpointProvider = null;
|
||||
this.endpoint = endpoint;
|
||||
}
|
||||
|
||||
public EndpointConnectionManager(Class<? extends Endpoint> endpointClass, String uriTemplate, Object... uriVars) {
|
||||
super(uriTemplate, uriVars);
|
||||
Assert.notNull(endpointClass, "endpointClass is required");
|
||||
Assert.notNull(endpointClass, "endpointClass must not be null");
|
||||
this.endpointProvider = new BeanCreatingHandlerProvider<Endpoint>(endpointClass);
|
||||
this.endpoint = null;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@ import org.springframework.web.util.UriComponentsBuilder;
|
|||
|
||||
/**
|
||||
* Initiates WebSocket requests to a WebSocket server programatically through the standard
|
||||
* Java WebSocket API .
|
||||
* Java WebSocket API.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
|
|
@ -62,15 +62,16 @@ public class StandardWebSocketClient implements WebSocketClient {
|
|||
}
|
||||
|
||||
public StandardWebSocketClient(WebSocketContainer webSocketContainer) {
|
||||
Assert.notNull(webSocketContainer, "webSocketContainer is required");
|
||||
Assert.notNull(webSocketContainer, "webSocketContainer must not be null");
|
||||
this.webSocketContainer = webSocketContainer;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public WebSocketSession doHandshake(WebSocketHandler webSocketHandler, String uriTemplate, Object... uriVariables)
|
||||
throws WebSocketConnectFailureException {
|
||||
|
||||
Assert.notNull(uriTemplate, "uriTemplate is required");
|
||||
Assert.notNull(uriTemplate, "uriTemplate must not be null");
|
||||
UriComponents uriComponents = UriComponentsBuilder.fromUriString(uriTemplate).buildAndExpand(uriVariables).encode();
|
||||
return doHandshake(webSocketHandler, null, uriComponents.toUri());
|
||||
}
|
||||
|
|
@ -79,8 +80,8 @@ public class StandardWebSocketClient implements WebSocketClient {
|
|||
public WebSocketSession doHandshake(WebSocketHandler webSocketHandler, HttpHeaders httpHeaders, URI uri)
|
||||
throws WebSocketConnectFailureException {
|
||||
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler is required");
|
||||
Assert.notNull(uri, "uri is required");
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler must not be null");
|
||||
Assert.notNull(uri, "uri must not be null");
|
||||
|
||||
httpHeaders = (httpHeaders != null) ? httpHeaders : new HttpHeaders();
|
||||
|
||||
|
|
|
|||
|
|
@ -32,8 +32,10 @@ import org.springframework.web.socket.client.WebSocketConnectFailureException;
|
|||
import org.springframework.web.util.UriComponents;
|
||||
import org.springframework.web.util.UriComponentsBuilder;
|
||||
|
||||
|
||||
/**
|
||||
* Initiates WebSocket requests to a WebSocket server programatically through the Jetty
|
||||
* WebSocket API.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
|
|
@ -134,8 +136,8 @@ public class JettyWebSocketClient implements WebSocketClient, SmartLifecycle {
|
|||
public WebSocketSession doHandshake(WebSocketHandler webSocketHandler, HttpHeaders headers, URI uri)
|
||||
throws WebSocketConnectFailureException {
|
||||
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler is required");
|
||||
Assert.notNull(uri, "uri is required");
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler must not be null");
|
||||
Assert.notNull(uri, "uri must not be null");
|
||||
|
||||
if (logger.isDebugEnabled()) {
|
||||
logger.debug("Connecting to " + uri);
|
||||
|
|
|
|||
|
|
@ -41,8 +41,8 @@ import org.springframework.web.socket.WebSocketHandler;
|
|||
|
||||
/**
|
||||
* A default implemnetation of {@link HandshakeHandler}.
|
||||
* <p>
|
||||
* A container-specific {@link RequestUpgradeStrategy} is required since standard Java
|
||||
*
|
||||
* <p>A container-specific {@link RequestUpgradeStrategy} is required since standard Java
|
||||
* WebSocket currently does not provide a way to initiate a WebSocket handshake.
|
||||
* Currently available are implementations for Tomcat and GlassFish.
|
||||
*
|
||||
|
|
@ -57,7 +57,7 @@ public class DefaultHandshakeHandler implements HandshakeHandler {
|
|||
|
||||
private List<String> supportedProtocols = new ArrayList<String>();
|
||||
|
||||
private RequestUpgradeStrategy requestUpgradeStrategy;
|
||||
private final RequestUpgradeStrategy requestUpgradeStrategy;
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -18,14 +18,13 @@ package org.springframework.web.socket.server;
|
|||
|
||||
import org.springframework.core.NestedRuntimeException;
|
||||
|
||||
|
||||
/**
|
||||
* Thrown when handshake processing failed to complete due to an internal, unrecoverable
|
||||
* error. This implies a server error (HTTP status code 500) as opposed to a failure in
|
||||
* the handshake negotiation.
|
||||
* <p>
|
||||
* By contrast, when handshake negotiation fails, the response status code will be 200 and
|
||||
* the response headers and body will have been updated to reflect the cause for the
|
||||
*
|
||||
* <p>By contrast, when handshake negotiation fails, the response status code will be 200
|
||||
* and the response headers and body will have been updated to reflect the cause for the
|
||||
* failure. A {@link HandshakeHandler} implementation will have protected methods to
|
||||
* customize updates to the response in those cases.
|
||||
*
|
||||
|
|
@ -35,7 +34,6 @@ import org.springframework.core.NestedRuntimeException;
|
|||
@SuppressWarnings("serial")
|
||||
public class HandshakeFailureException extends NestedRuntimeException {
|
||||
|
||||
|
||||
public HandshakeFailureException(String msg, Throwable cause) {
|
||||
super(msg, cause);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ import org.springframework.web.socket.support.PerConnectionWebSocketHandler;
|
|||
*/
|
||||
public interface HandshakeHandler {
|
||||
|
||||
|
||||
/**
|
||||
* Initiate the handshake.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -43,10 +43,10 @@ import org.springframework.util.ReflectionUtils;
|
|||
* {@link ServerEndpoint} and registers them as well. Although not required, it is likely
|
||||
* annotated endpoints should have their {@code configurator} property set to
|
||||
* {@link SpringConfigurator}.
|
||||
* <p>
|
||||
* When this class is used, by declaring it in Spring configuration, it should be possible
|
||||
* to turn off a Servlet container's scan for WebSocket endpoints. This can be done with
|
||||
* the help of the {@code <absolute-ordering>} element in web.xml.
|
||||
*
|
||||
* <p>When this class is used, by declaring it in Spring configuration, it should be
|
||||
* possible to turn off a Servlet container's scan for WebSocket endpoints. This can be
|
||||
* done with the help of the {@code <absolute-ordering>} element in web.xml.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
|
|
@ -123,7 +123,7 @@ public class ServerEndpointExporter implements InitializingBean, BeanPostProcess
|
|||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
Assert.notNull(serverContainer, "javax.websocket.server.ServerContainer not available");
|
||||
Assert.state(this.serverContainer != null, "javax.websocket.server.ServerContainer not available");
|
||||
|
||||
List<Class<?>> allClasses = new ArrayList<Class<?>>(this.annotatedEndpointClasses);
|
||||
allClasses.addAll(this.annotatedEndpointBeanTypes);
|
||||
|
|
|
|||
|
|
@ -35,14 +35,13 @@ import org.springframework.beans.factory.BeanFactoryAware;
|
|||
import org.springframework.util.Assert;
|
||||
import org.springframework.web.socket.support.BeanCreatingHandlerProvider;
|
||||
|
||||
|
||||
/**
|
||||
* An implementation of {@link javax.websocket.server.ServerEndpointConfig} that also
|
||||
* contains the target {@link javax.websocket.Endpoint}, provided either as a reference or
|
||||
* as a bean name.
|
||||
* <p>
|
||||
* {@link ServerEndpointRegistration} beans are detected by {@link ServerEndpointExporter}
|
||||
* and registered with a Java WebSocket runtime at startup.
|
||||
*
|
||||
* <p>{@link ServerEndpointRegistration} beans are detected by
|
||||
* {@link ServerEndpointExporter} and registered with a Java WebSocket runtime at startup.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
|
|
@ -67,26 +66,32 @@ public class ServerEndpointRegistration implements ServerEndpointConfig, BeanFac
|
|||
|
||||
private final Map<String, Object> userProperties = new HashMap<String, Object>();
|
||||
|
||||
private Configurator configurator = new EndpointRegistrationConfigurator();
|
||||
private final Configurator configurator = new EndpointRegistrationConfigurator();
|
||||
|
||||
|
||||
/**
|
||||
* Class constructor with the {@code javax.webscoket.Endpoint} class.
|
||||
*
|
||||
* @param path
|
||||
* @param endpointClass
|
||||
* Create a new {@link ServerEndpointRegistration} instance from an
|
||||
* {@code javax.webscoket.Endpoint} class.
|
||||
* @param path the endpoint path
|
||||
* @param endpointClass the endpoint class
|
||||
*/
|
||||
public ServerEndpointRegistration(String path, Class<? extends Endpoint> endpointClass) {
|
||||
Assert.hasText(path, "path must not be empty");
|
||||
Assert.notNull(endpointClass, "endpointClass is required");
|
||||
Assert.notNull(endpointClass, "endpointClass must not be null");
|
||||
this.path = path;
|
||||
this.endpointProvider = new BeanCreatingHandlerProvider<Endpoint>(endpointClass);
|
||||
this.endpoint = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new {@link ServerEndpointRegistration} instance from an
|
||||
* {@code javax.webscoket.Endpoint} instance.
|
||||
* @param path the endpoint path
|
||||
* @param endpoint the endpoint instance
|
||||
*/
|
||||
public ServerEndpointRegistration(String path, Endpoint endpoint) {
|
||||
Assert.hasText(path, "path must not be empty");
|
||||
Assert.notNull(endpoint, "endpoint is required");
|
||||
Assert.notNull(endpoint, "endpoint must not be null");
|
||||
this.path = path;
|
||||
this.endpointProvider = null;
|
||||
this.endpoint = endpoint;
|
||||
|
|
@ -188,7 +193,7 @@ public class ServerEndpointRegistration implements ServerEndpointConfig, BeanFac
|
|||
@SuppressWarnings("unchecked")
|
||||
@Override
|
||||
public <T> T getEndpointInstance(Class<T> clazz) throws InstantiationException {
|
||||
return (T) ServerEndpointRegistration.this.getEndpoint();
|
||||
return (T) getEndpoint();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -33,9 +33,9 @@ import org.springframework.web.socket.sockjs.SockJsService;
|
|||
* {@code javax.servlet.ServletContext} attribute, simply declaring this FactoryBean and
|
||||
* using its setters allows configuring the {@code ServerContainer} through Spring
|
||||
* configuration.
|
||||
* <p>
|
||||
* This is useful even if the {@code ServerContainer} is not injected into any other bean.
|
||||
* For example, an application can configure a {@link DefaultHandshakeHandler}, a
|
||||
*
|
||||
* <p>This is useful even if the {@code ServerContainer} is not injected into any other
|
||||
* bean. For example, an application can configure a {@link DefaultHandshakeHandler}, a
|
||||
* {@link SockJsService}, or {@link ServerEndpointExporter}, and separately declare this
|
||||
* FactoryBean in order to customize the properties of the (one and only)
|
||||
* {@code ServerContainer} instance.
|
||||
|
|
@ -112,8 +112,8 @@ public class ServletServerContainerFactoryBean
|
|||
@Override
|
||||
public void afterPropertiesSet() throws Exception {
|
||||
|
||||
Assert.notNull(this.serverContainer,
|
||||
"A ServletContext is required to access the javax.websocket.server.ServerContainer instance");
|
||||
Assert.state(this.serverContainer != null, "A ServletContext is required to "
|
||||
+ "access the javax.websocket.server.ServerContainer instance");
|
||||
|
||||
if (this.asyncSendTimeout != null) {
|
||||
this.serverContainer.setAsyncSendTimeout(this.asyncSendTimeout);
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ import org.springframework.web.context.WebApplicationContext;
|
|||
/**
|
||||
* A {@link javax.websocket.server.ServerEndpointConfig.Configurator} for initializing
|
||||
* {@link ServerEndpoint}-annotated classes through Spring.
|
||||
*
|
||||
* <p>
|
||||
* <pre class="code">
|
||||
* @ServerEndpoint(value = "/echo", configurator = SpringConfigurator.class)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import org.springframework.http.server.ServerHttpResponse;
|
|||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.adapter.ConfigurableWebSocketSession;
|
||||
|
||||
|
||||
/**
|
||||
* Copies information from the handshake HTTP request and response to a given
|
||||
* {@link WebSocketSession}.
|
||||
|
|
@ -31,7 +30,6 @@ import org.springframework.web.socket.adapter.ConfigurableWebSocketSession;
|
|||
*/
|
||||
public class ServerWebSocketSessionInitializer {
|
||||
|
||||
|
||||
public void initialize(ServerHttpRequest request, ServerHttpResponse response, ConfigurableWebSocketSession session) {
|
||||
session.setUri(request.getURI());
|
||||
session.setRemoteHostName(request.getRemoteHostName());
|
||||
|
|
|
|||
|
|
@ -35,14 +35,15 @@ import org.springframework.web.socket.support.ExceptionWebSocketHandlerDecorator
|
|||
import org.springframework.web.socket.support.LoggingWebSocketHandlerDecorator;
|
||||
|
||||
/**
|
||||
* An {@link HttpRequestHandler} for processing WebSocket handshake requests.
|
||||
* <p>
|
||||
* This is the main class to use when configuring a server WebSocket at a specific URL. It
|
||||
* is a very thin wrapper around a {@link HandshakeHandler} and a {@link WebSocketHandler}
|
||||
* instance also adapting the {@link HttpServletRequest} and {@link HttpServletResponse}
|
||||
* to {@link ServerHttpRequest} and {@link ServerHttpResponse} respectively.
|
||||
* <p>
|
||||
* The {@link #decorateWebSocketHandler(WebSocketHandler)} method decorates the given
|
||||
* A {@link HttpRequestHandler} for processing WebSocket handshake requests.
|
||||
*
|
||||
* <p>This is the main class to use when configuring a server WebSocket at a specific URL.
|
||||
* It is a very thin wrapper around a {@link HandshakeHandler} and a
|
||||
* {@link WebSocketHandler} instance also adapting the {@link HttpServletRequest} and
|
||||
* {@link HttpServletResponse} to {@link ServerHttpRequest} and {@link ServerHttpResponse}
|
||||
* respectively.
|
||||
*
|
||||
* <p>The {@link #decorateWebSocketHandler(WebSocketHandler)} method decorates the given
|
||||
* WebSocketHandler with a logging and exception handling decorators. This method can
|
||||
* be overridden to change that.
|
||||
*
|
||||
|
|
@ -61,16 +62,17 @@ public class WebSocketHttpRequestHandler implements HttpRequestHandler {
|
|||
}
|
||||
|
||||
public WebSocketHttpRequestHandler( WebSocketHandler webSocketHandler, HandshakeHandler handshakeHandler) {
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler is required");
|
||||
Assert.notNull(handshakeHandler, "handshakeHandler is required");
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler must not be null");
|
||||
Assert.notNull(handshakeHandler, "handshakeHandler must not be null");
|
||||
this.webSocketHandler = decorateWebSocketHandler(webSocketHandler);
|
||||
this.handshakeHandler = new DefaultHandshakeHandler();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decorate the WebSocketHandler provided to the class constructor.
|
||||
* <p>
|
||||
* By default {@link ExceptionWebSocketHandlerDecorator} and
|
||||
*
|
||||
* <p>By default {@link ExceptionWebSocketHandlerDecorator} and
|
||||
* {@link LoggingWebSocketHandlerDecorator} are applied are added.
|
||||
*/
|
||||
protected WebSocketHandler decorateWebSocketHandler(WebSocketHandler handler) {
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.socket.sockjs;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -27,6 +28,7 @@ import java.util.List;
|
|||
import java.util.Random;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
|
@ -48,8 +50,8 @@ import org.springframework.web.socket.WebSocketHandler;
|
|||
* support, SockJS path resolution, and processing for static SockJS requests (e.g.
|
||||
* "/info", "/iframe.html", etc). Sub-classes are responsible for handling transport
|
||||
* requests.
|
||||
* <p>
|
||||
* It is expected that this service is mapped correctly to one or more prefixes such as
|
||||
*
|
||||
* <p>It is expected that this service is mapped correctly to one or more prefixes such as
|
||||
* "/echo" including all sub-URLs (e.g. "/echo/**"). A SockJS service itself is generally
|
||||
* unaware of request mapping details but nevertheless must be able to extract the SockJS
|
||||
* path, which is the portion of the request path following the prefix. In most cases,
|
||||
|
|
@ -63,7 +65,7 @@ public abstract class AbstractSockJsService implements SockJsService, SockJsConf
|
|||
|
||||
protected final Log logger = LogFactory.getLog(getClass());
|
||||
|
||||
private static final int ONE_YEAR = 365 * 24 * 60 * 60;
|
||||
private static final long ONE_YEAR = TimeUnit.DAYS.toSeconds(365);
|
||||
|
||||
|
||||
private String name = "SockJSService@" + ObjectUtils.getIdentityHexString(this);
|
||||
|
|
@ -88,10 +90,11 @@ public abstract class AbstractSockJsService implements SockJsService, SockJsConf
|
|||
|
||||
|
||||
public AbstractSockJsService(TaskScheduler scheduler) {
|
||||
Assert.notNull(scheduler, "scheduler is required");
|
||||
Assert.notNull(scheduler, "scheduler must not be null");
|
||||
this.taskScheduler = scheduler;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* A unique name for the service mainly for logging purposes.
|
||||
*/
|
||||
|
|
@ -107,8 +110,8 @@ public abstract class AbstractSockJsService implements SockJsService, SockJsConf
|
|||
* Use this property to configure one or more prefixes that this SockJS service is
|
||||
* allowed to serve. The prefix (e.g. "/echo") is needed to extract the SockJS
|
||||
* specific portion of the URL (e.g. "${prefix}/info", "${prefix}/iframe.html", etc).
|
||||
* <p>
|
||||
* This property is not strictly required. In most cases, the SockJS path can be
|
||||
*
|
||||
* <p>This property is not strictly required. In most cases, the SockJS path can be
|
||||
* auto-detected since the initial request from the SockJS client is of the form
|
||||
* "{prefix}/info". Assuming the SockJS service is mapped correctly (e.g. using
|
||||
* Ant-style pattern "/echo/**") this should work fine. This property can be used
|
||||
|
|
@ -144,8 +147,8 @@ public abstract class AbstractSockJsService implements SockJsService, SockJsConf
|
|||
* a domain local to the SockJS server. The iframe does need to load the
|
||||
* SockJS javascript client library and this option allows configuring its
|
||||
* url.
|
||||
* <p>
|
||||
* By default this is set to point to
|
||||
*
|
||||
* <p>By default this is set to point to
|
||||
* "https://d1fxtkz8shb9d2.cloudfront.net/sockjs-0.3.4.min.js".
|
||||
*/
|
||||
public AbstractSockJsService setSockJsClientLibraryUrl(String clientLibraryUrl) {
|
||||
|
|
@ -168,15 +171,15 @@ public abstract class AbstractSockJsService implements SockJsService, SockJsConf
|
|||
|
||||
@Override
|
||||
public int getStreamBytesLimit() {
|
||||
return streamBytesLimit;
|
||||
return this.streamBytesLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* Some load balancers do sticky sessions, but only if there is a JSESSIONID
|
||||
* cookie. Even if it is set to a dummy value, it doesn't matter since
|
||||
* session information is added by the load balancer.
|
||||
* <p>
|
||||
* Set this option to indicate if a JSESSIONID cookie should be created. The
|
||||
*
|
||||
* <p>Set this option to indicate if a JSESSIONID cookie should be created. The
|
||||
* default value is "true".
|
||||
*/
|
||||
public AbstractSockJsService setJsessionIdCookieRequired(boolean jsessionIdCookieRequired) {
|
||||
|
|
@ -211,8 +214,8 @@ public abstract class AbstractSockJsService implements SockJsService, SockJsConf
|
|||
* The amount of time in milliseconds before a client is considered
|
||||
* disconnected after not having a receiving connection, i.e. an active
|
||||
* connection over which the server can send data to the client.
|
||||
* <p>
|
||||
* The default value is 5000.
|
||||
*
|
||||
* <p>The default value is 5000.
|
||||
*/
|
||||
public void setDisconnectDelay(long disconnectDelay) {
|
||||
this.disconnectDelay = disconnectDelay;
|
||||
|
|
@ -228,8 +231,8 @@ public abstract class AbstractSockJsService implements SockJsService, SockJsConf
|
|||
/**
|
||||
* Some load balancers don't support websockets. This option can be used to
|
||||
* disable the WebSocket transport on the server side.
|
||||
* <p>
|
||||
* The default value is "true".
|
||||
*
|
||||
* <p>The default value is "true".
|
||||
*/
|
||||
public void setWebSocketsEnabled(boolean webSocketsEnabled) {
|
||||
this.webSocketsEnabled = webSocketsEnabled;
|
||||
|
|
@ -245,12 +248,6 @@ public abstract class AbstractSockJsService implements SockJsService, SockJsConf
|
|||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @param request
|
||||
* @param response
|
||||
* @param sockJsPath
|
||||
*
|
||||
* @throws Exception
|
||||
*/
|
||||
@Override
|
||||
public final void handleRequest(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler)
|
||||
|
|
@ -441,6 +438,7 @@ public abstract class AbstractSockJsService implements SockJsService, SockJsConf
|
|||
void handle(ServerHttpRequest request, ServerHttpResponse response) throws IOException;
|
||||
}
|
||||
|
||||
|
||||
private static final Random random = new Random();
|
||||
|
||||
private final SockJsRequestHandler infoHandler = new SockJsRequestHandler() {
|
||||
|
|
|
|||
|
|
@ -34,7 +34,6 @@ import org.springframework.web.socket.WebSocketMessage;
|
|||
import org.springframework.web.socket.WebSocketSession;
|
||||
import org.springframework.web.socket.adapter.ConfigurableWebSocketSession;
|
||||
|
||||
|
||||
/**
|
||||
* An abstract base class SockJS sessions implementing {@link WebSocketSession}.
|
||||
*
|
||||
|
|
@ -58,24 +57,26 @@ public abstract class AbstractSockJsSession implements ConfigurableWebSocketSess
|
|||
|
||||
private final SockJsConfiguration sockJsConfig;
|
||||
|
||||
private WebSocketHandler handler;
|
||||
private final WebSocketHandler handler;
|
||||
|
||||
private State state = State.NEW;
|
||||
|
||||
private long timeCreated = System.currentTimeMillis();
|
||||
private final long timeCreated = System.currentTimeMillis();
|
||||
|
||||
private long timeLastActive = timeCreated;
|
||||
private long timeLastActive = this.timeCreated;
|
||||
|
||||
private ScheduledFuture<?> heartbeatTask;
|
||||
|
||||
|
||||
/**
|
||||
* @param sessionId
|
||||
* @param sessionId the session ID
|
||||
* @param config the sockJS configuration
|
||||
* @param webSocketHandler the recipient of SockJS messages
|
||||
*/
|
||||
public AbstractSockJsSession(String sessionId, SockJsConfiguration config, WebSocketHandler webSocketHandler) {
|
||||
Assert.notNull(sessionId, "sessionId is required");
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler is required");
|
||||
public AbstractSockJsSession(String sessionId, SockJsConfiguration config,
|
||||
WebSocketHandler webSocketHandler) {
|
||||
Assert.notNull(sessionId, "sessionId must not be null");
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler must not be null");
|
||||
this.id = sessionId;
|
||||
this.handler = webSocketHandler;
|
||||
this.sockJsConfig = config;
|
||||
|
|
@ -191,7 +192,7 @@ public abstract class AbstractSockJsSession implements ConfigurableWebSocketSess
|
|||
/**
|
||||
* Invoked in reaction to the underlying connection being closed by the remote side
|
||||
* (or the WebSocket container) in order to perform cleanup and notify the
|
||||
* {@link TextMessageHandler}. This is in contrast to {@link #close()} that pro-actively
|
||||
* {@link WebSocketHandler}. This is in contrast to {@link #close()} that pro-actively
|
||||
* closes the connection.
|
||||
*/
|
||||
public final void delegateConnectionClosed(CloseStatus status) throws Exception {
|
||||
|
|
@ -224,7 +225,8 @@ public abstract class AbstractSockJsSession implements ConfigurableWebSocketSess
|
|||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>Performs cleanup and notifies the {@link SockJsHandler}.
|
||||
*
|
||||
* <p>Performs cleanup and notifies the {@link WebSocketHandler}.
|
||||
*/
|
||||
@Override
|
||||
public final void close() throws IOException {
|
||||
|
|
@ -233,7 +235,8 @@ public abstract class AbstractSockJsSession implements ConfigurableWebSocketSess
|
|||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
* <p>Performs cleanup and notifies the {@link SockJsHandler}.
|
||||
*
|
||||
* <p>Performs cleanup and notifies the {@link WebSocketHandler}.
|
||||
*/
|
||||
@Override
|
||||
public final void close(CloseStatus status) throws IOException {
|
||||
|
|
@ -329,7 +332,7 @@ public abstract class AbstractSockJsSession implements ConfigurableWebSocketSess
|
|||
}
|
||||
|
||||
protected void scheduleHeartbeat() {
|
||||
Assert.notNull(this.sockJsConfig.getTaskScheduler(), "heartbeatScheduler not configured");
|
||||
Assert.state(this.sockJsConfig.getTaskScheduler() != null, "heartbeatScheduler not configured");
|
||||
cancelHeartbeat();
|
||||
if (!isActive()) {
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -35,8 +35,8 @@ public interface SockJsConfiguration {
|
|||
* closed. After that client will open a new request. Setting this value to
|
||||
* one effectively disables streaming and will make streaming transports to
|
||||
* behave like polling transports.
|
||||
* <p>
|
||||
* The default value is 128K (i.e. 128 * 1024).
|
||||
*
|
||||
* <p>The default value is 128K (i.e. 128 * 1024).
|
||||
*/
|
||||
public int getStreamBytesLimit();
|
||||
|
||||
|
|
@ -44,8 +44,8 @@ public interface SockJsConfiguration {
|
|||
* The amount of time in milliseconds when the server has not sent any
|
||||
* messages and after which the server should send a heartbeat frame to the
|
||||
* client in order to keep the connection from breaking.
|
||||
* <p>
|
||||
* The default value is 25,000 (25 seconds).
|
||||
*
|
||||
* <p>The default value is 25,000 (25 seconds).
|
||||
*/
|
||||
public long getHeartbeatTime();
|
||||
|
||||
|
|
|
|||
|
|
@ -44,7 +44,7 @@ public class SockJsFrame {
|
|||
|
||||
|
||||
private SockJsFrame(String content) {
|
||||
Assert.notNull("content is required");
|
||||
Assert.notNull("content must not be null");
|
||||
this.content = content;
|
||||
}
|
||||
|
||||
|
|
@ -144,7 +144,7 @@ public class SockJsFrame {
|
|||
}
|
||||
|
||||
public static String prepareContent(String... messages) {
|
||||
Assert.notNull(messages, "messages required");
|
||||
Assert.notNull(messages, "messages must not be null");
|
||||
StringBuilder sb = new StringBuilder();
|
||||
sb.append("a[");
|
||||
for (int i=0; i < messages.length; i++) {
|
||||
|
|
@ -172,14 +172,12 @@ public class SockJsFrame {
|
|||
private final String format;
|
||||
|
||||
public DefaultFrameFormat(String format) {
|
||||
Assert.notNull(format, "format is required");
|
||||
Assert.notNull(format, "format must not be null");
|
||||
this.format = format;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param format a String with a single %s formatting character where the
|
||||
* frame content is to be inserted; e.g. "data: %s\r\n\r\n"
|
||||
* @param frame the SockJs frame.
|
||||
* @return new SockJsFrame instance with the formatted content
|
||||
*/
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -32,7 +32,6 @@ import org.springframework.web.socket.WebSocketHandler;
|
|||
*/
|
||||
public interface SockJsService {
|
||||
|
||||
|
||||
void handleRequest(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler handler)
|
||||
throws IOException, TransportErrorException;
|
||||
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import org.springframework.web.socket.WebSocketHandler;
|
|||
* A factory for creating a SockJS session. {@link TransportHandler}s typically also serve
|
||||
* as SockJS session factories.
|
||||
*
|
||||
* @param <S> The type of session being created
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -19,15 +19,14 @@ package org.springframework.web.socket.sockjs;
|
|||
import org.springframework.core.NestedRuntimeException;
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
|
||||
|
||||
/**
|
||||
* Raised when a TransportHandler fails during request processing.
|
||||
* <p>
|
||||
* If the underlying exception occurs while sending messages to the client, the session is
|
||||
* closed and the {@link WebSocketHandler} notified.
|
||||
* <p>
|
||||
* If the underlying exception occurs while processing an incoming HTTP request, including
|
||||
* over HTTP POST, the session will remain open. Only the incoming request is rejected.
|
||||
* Raised when a TransportHandler fails during request processing. If the underlying
|
||||
* exception occurs while sending messages to the client, the session is closed and the
|
||||
* {@link WebSocketHandler} notified.
|
||||
*
|
||||
* <p>If the underlying exception occurs while processing an incoming HTTP request,
|
||||
* including over HTTP POST, the session will remain open. Only the incoming request is
|
||||
* rejected.
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
|
|
@ -43,7 +42,7 @@ public class TransportErrorException extends NestedRuntimeException {
|
|||
}
|
||||
|
||||
public String getSockJsSessionId() {
|
||||
return sockJsSessionId;
|
||||
return this.sockJsSessionId;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@
|
|||
package org.springframework.web.socket.sockjs;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
|
@ -54,12 +55,13 @@ public enum TransportType {
|
|||
|
||||
private final List<String> headerHints;
|
||||
|
||||
private static final Map<String, TransportType> transportTypes = new HashMap<String, TransportType>();
|
||||
|
||||
private static final Map<String, TransportType> TRANSPORT_TYPES;
|
||||
static {
|
||||
Map<String, TransportType> transportTypes = new HashMap<String, TransportType>();
|
||||
for (TransportType type : values()) {
|
||||
transportTypes.put(type.value, type);
|
||||
}
|
||||
TRANSPORT_TYPES = Collections.unmodifiableMap(transportTypes);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -94,7 +96,7 @@ public enum TransportType {
|
|||
}
|
||||
|
||||
public static TransportType fromValue(String value) {
|
||||
return transportTypes.get(value);
|
||||
return TRANSPORT_TYPES.get(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@ public class DefaultSockJsService extends AbstractSockJsService {
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
protected final Set<TransportHandler> getDefaultTransportHandlers() {
|
||||
Set<TransportHandler> result = new HashSet<TransportHandler>();
|
||||
result.add(new XhrPollingTransportHandler());
|
||||
|
|
|
|||
|
|
@ -34,14 +34,13 @@ import org.springframework.web.socket.support.ExceptionWebSocketHandlerDecorator
|
|||
import org.springframework.web.socket.support.LoggingWebSocketHandlerDecorator;
|
||||
|
||||
/**
|
||||
* An {@link HttpRequestHandler} for processing SockJS requests.
|
||||
* <p>
|
||||
* This is the main class to use when configuring a SockJS service at a specific URL. It
|
||||
* is a very thin wrapper around a {@link SockJsService} and a {@link WebSocketHandler}
|
||||
* instance also adapting the {@link HttpServletRequest} and {@link HttpServletResponse}
|
||||
* to {@link ServerHttpRequest} and {@link ServerHttpResponse} respectively.
|
||||
* <p>
|
||||
* The {@link #decorateWebSocketHandler(WebSocketHandler)} method decorates the given
|
||||
* An {@link HttpRequestHandler} for processing SockJS requests. This is the main class
|
||||
* to use when configuring a SockJS service at a specific URL. It is a very thin wrapper
|
||||
* around a {@link SockJsService} and a {@link WebSocketHandler} instance also adapting
|
||||
* the {@link HttpServletRequest} and {@link HttpServletResponse} to
|
||||
* {@link ServerHttpRequest} and {@link ServerHttpResponse} respectively.
|
||||
*
|
||||
* <p>The {@link #decorateWebSocketHandler(WebSocketHandler)} method decorates the given
|
||||
* WebSocketHandler with a logging and exception handling decorators. This method can be
|
||||
* overridden to change that.
|
||||
*
|
||||
|
|
@ -56,19 +55,22 @@ public class SockJsHttpRequestHandler implements HttpRequestHandler {
|
|||
|
||||
|
||||
/**
|
||||
* Class constructor with {@link SockJsHandler} instance ...
|
||||
* Create a new {@link SockJsHttpRequestHandler}.
|
||||
* @param sockJsService the SockJS service
|
||||
* @param webSocketHandler the websocket handler
|
||||
*/
|
||||
public SockJsHttpRequestHandler(SockJsService sockJsService, WebSocketHandler webSocketHandler) {
|
||||
Assert.notNull(sockJsService, "sockJsService is required");
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler is required");
|
||||
Assert.notNull(sockJsService, "sockJsService must not be null");
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler must not be null");
|
||||
this.sockJsService = sockJsService;
|
||||
this.webSocketHandler = decorateWebSocketHandler(webSocketHandler);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decorate the WebSocketHandler provided to the class constructor.
|
||||
* <p>
|
||||
* By default {@link ExceptionWebSocketHandlerDecorator} and
|
||||
*
|
||||
* <p>By default {@link ExceptionWebSocketHandlerDecorator} and
|
||||
* {@link LoggingWebSocketHandlerDecorator} are applied are added.
|
||||
*/
|
||||
protected WebSocketHandler decorateWebSocketHandler(WebSocketHandler handler) {
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ public abstract class AbstractHttpSockJsSession extends AbstractSockJsSession {
|
|||
super(sessionId, config, handler);
|
||||
}
|
||||
|
||||
|
||||
public synchronized void setInitialRequest(ServerHttpRequest request, ServerHttpResponse response,
|
||||
FrameFormat frameFormat) throws TransportErrorException {
|
||||
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ public class EventSourceTransportHandler extends AbstractHttpSendingTransportHan
|
|||
|
||||
@Override
|
||||
public StreamingSockJsSession createSession(String sessionId, WebSocketHandler handler) {
|
||||
Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration");
|
||||
Assert.state(getSockJsConfig() != null, "This transport requires SockJsConfiguration");
|
||||
return new StreamingSockJsSession(sessionId, getSockJsConfig(), handler) {
|
||||
@Override
|
||||
protected void writePrelude() throws IOException {
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ public class HtmlFileTransportHandler extends AbstractHttpSendingTransportHandle
|
|||
|
||||
private static final String PARTIAL_HTML_CONTENT;
|
||||
|
||||
// Safari needs at least 1024 bytes to parse the website.
|
||||
// http://code.google.com/p/browsersec/wiki/Part2#Survey_of_content_sniffing_behaviors
|
||||
private static final int MINIMUM_PARTIAL_HTML_CONTENT_LENGTH = 1024;
|
||||
|
||||
static {
|
||||
StringBuilder sb = new StringBuilder(
|
||||
"<!doctype html>\n" +
|
||||
|
|
@ -61,11 +65,8 @@ public class HtmlFileTransportHandler extends AbstractHttpSendingTransportHandle
|
|||
" </script>"
|
||||
);
|
||||
|
||||
// Safari needs at least 1024 bytes to parse the website.
|
||||
// http://code.google.com/p/browsersec/wiki/Part2#Survey_of_content_sniffing_behaviors
|
||||
int spaces = 1024 - sb.length();
|
||||
for (int i=0; i < spaces; i++) {
|
||||
sb.append(' ');
|
||||
while(sb.length() < MINIMUM_PARTIAL_HTML_CONTENT_LENGTH) {
|
||||
sb.append(" ");
|
||||
}
|
||||
|
||||
PARTIAL_HTML_CONTENT = sb.toString();
|
||||
|
|
@ -84,7 +85,7 @@ public class HtmlFileTransportHandler extends AbstractHttpSendingTransportHandle
|
|||
|
||||
@Override
|
||||
public StreamingSockJsSession createSession(String sessionId, WebSocketHandler handler) {
|
||||
Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration");
|
||||
Assert.state(getSockJsConfig() != null, "This transport requires SockJsConfiguration");
|
||||
|
||||
return new StreamingSockJsSession(sessionId, getSockJsConfig(), handler) {
|
||||
|
||||
|
|
|
|||
|
|
@ -51,7 +51,7 @@ public class JsonpPollingTransportHandler extends AbstractHttpSendingTransportHa
|
|||
|
||||
@Override
|
||||
public PollingSockJsSession createSession(String sessionId, WebSocketHandler handler) {
|
||||
Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration");
|
||||
Assert.state(getSockJsConfig() != null, "This transport requires SockJsConfiguration");
|
||||
return new PollingSockJsSession(sessionId, getSockJsConfig(), handler);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.socket.sockjs.transport;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -32,6 +33,7 @@ public class PollingSockJsSession extends AbstractHttpSockJsSession {
|
|||
super(sessionId, config, handler);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void flushCache() throws IOException {
|
||||
cancelHeartbeat();
|
||||
|
|
|
|||
|
|
@ -26,13 +26,12 @@ import org.springframework.web.socket.WebSocketSession;
|
|||
import org.springframework.web.socket.adapter.TextWebSocketHandlerAdapter;
|
||||
import org.springframework.web.socket.sockjs.SockJsConfiguration;
|
||||
|
||||
|
||||
/**
|
||||
* An implementation of {@link WebSocketHandler} that adds SockJS messages frames, sends
|
||||
* SockJS heartbeat messages, and delegates lifecycle events and messages to a target
|
||||
* {@link WebSocketHandler}.
|
||||
* <p>
|
||||
* Methods in this class allow exceptions from the wrapped {@link WebSocketHandler} to
|
||||
*
|
||||
* <p>Methods in this class allow exceptions from the wrapped {@link WebSocketHandler} to
|
||||
* propagate. However, any exceptions resulting from SockJS message handling (e.g. while
|
||||
* sending SockJS frames or heartbeat messages) are caught and treated as transport
|
||||
* errors, i.e. routed to the
|
||||
|
|
@ -46,7 +45,7 @@ public class SockJsWebSocketHandler extends TextWebSocketHandlerAdapter {
|
|||
|
||||
private final SockJsConfiguration sockJsConfig;
|
||||
|
||||
private WebSocketServerSockJsSession session;
|
||||
private final WebSocketServerSockJsSession session;
|
||||
|
||||
private final AtomicInteger sessionCount = new AtomicInteger(0);
|
||||
|
||||
|
|
@ -54,9 +53,9 @@ public class SockJsWebSocketHandler extends TextWebSocketHandlerAdapter {
|
|||
public SockJsWebSocketHandler(SockJsConfiguration config,
|
||||
WebSocketHandler webSocketHandler, WebSocketServerSockJsSession session) {
|
||||
|
||||
Assert.notNull(config, "sockJsConfig is required");
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler is required");
|
||||
Assert.notNull(session, "session is required");
|
||||
Assert.notNull(config, "config must not be null");
|
||||
Assert.notNull(webSocketHandler, "webSocketHandler must not be null");
|
||||
Assert.notNull(session, "session must not be null");
|
||||
|
||||
this.sockJsConfig = config;
|
||||
this.session = session;
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import org.springframework.web.socket.sockjs.SockJsFrame;
|
|||
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
|
||||
|
||||
/**
|
||||
* A SockJS session for use with the WebSocket transport.
|
||||
*
|
||||
|
|
@ -48,6 +47,7 @@ public class WebSocketServerSockJsSession extends AbstractSockJsSession {
|
|||
super(sessionId, config, handler);
|
||||
}
|
||||
|
||||
|
||||
public void initWebSocketSession(WebSocketSession session) throws Exception {
|
||||
this.webSocketSession = session;
|
||||
try {
|
||||
|
|
@ -75,7 +75,7 @@ public class WebSocketServerSockJsSession extends AbstractSockJsSession {
|
|||
}
|
||||
String[] messages;
|
||||
try {
|
||||
messages = objectMapper.readValue(payload, String[].class);
|
||||
messages = this.objectMapper.readValue(payload, String[].class);
|
||||
}
|
||||
catch (IOException ex) {
|
||||
logger.error("Broken data received. Terminating WebSocket connection abruptly", ex);
|
||||
|
|
|
|||
|
|
@ -31,12 +31,11 @@ import org.springframework.web.socket.sockjs.TransportErrorException;
|
|||
import org.springframework.web.socket.sockjs.TransportHandler;
|
||||
import org.springframework.web.socket.sockjs.TransportType;
|
||||
|
||||
|
||||
/**
|
||||
* A WebSocket {@link TransportHandler}. Uses {@link SockJsWebSocketHandler} and
|
||||
* {@link WebSocketServerSockJsSession} to add SockJS processing.
|
||||
* <p>
|
||||
* Also implements {@link HandshakeHandler} to support raw WebSocket communication at
|
||||
*
|
||||
* <p>Also implements {@link HandshakeHandler} to support raw WebSocket communication at
|
||||
* SockJS URL "/websocket".
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
|
|
@ -51,10 +50,11 @@ public class WebSocketTransportHandler implements ConfigurableTransportHandler,
|
|||
|
||||
|
||||
public WebSocketTransportHandler(HandshakeHandler handshakeHandler) {
|
||||
Assert.notNull(handshakeHandler, "handshakeHandler is required");
|
||||
Assert.notNull(handshakeHandler, "handshakeHandler must not be null");
|
||||
this.handshakeHandler = handshakeHandler;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public TransportType getTransportType() {
|
||||
return TransportType.WEBSOCKET;
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.socket.sockjs.transport;
|
||||
|
||||
import java.nio.charset.Charset;
|
||||
|
|
@ -26,7 +27,6 @@ import org.springframework.web.socket.sockjs.SockJsFrame.FrameFormat;
|
|||
import org.springframework.web.socket.sockjs.TransportHandler;
|
||||
import org.springframework.web.socket.sockjs.TransportType;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link TransportHandler} based on XHR (long) polling.
|
||||
*
|
||||
|
|
@ -35,7 +35,6 @@ import org.springframework.web.socket.sockjs.TransportType;
|
|||
*/
|
||||
public class XhrPollingTransportHandler extends AbstractHttpSendingTransportHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public TransportType getTransportType() {
|
||||
return TransportType.XHR;
|
||||
|
|
@ -53,7 +52,7 @@ public class XhrPollingTransportHandler extends AbstractHttpSendingTransportHand
|
|||
|
||||
@Override
|
||||
public PollingSockJsSession createSession(String sessionId, WebSocketHandler handler) {
|
||||
Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration");
|
||||
Assert.state(getSockJsConfig() != null, "This transport requires SockJsConfiguration");
|
||||
return new PollingSockJsSession(sessionId, getSockJsConfig(), handler);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.socket.sockjs.transport;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -27,7 +28,6 @@ import org.springframework.web.socket.sockjs.SockJsFrame.FrameFormat;
|
|||
import org.springframework.web.socket.sockjs.TransportHandler;
|
||||
import org.springframework.web.socket.sockjs.TransportType;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link TransportHandler} that sends messages over an HTTP streaming request.
|
||||
*
|
||||
|
|
@ -36,7 +36,6 @@ import org.springframework.web.socket.sockjs.TransportType;
|
|||
*/
|
||||
public class XhrStreamingTransportHandler extends AbstractHttpSendingTransportHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public TransportType getTransportType() {
|
||||
return TransportType.XHR_STREAMING;
|
||||
|
|
@ -49,7 +48,7 @@ public class XhrStreamingTransportHandler extends AbstractHttpSendingTransportHa
|
|||
|
||||
@Override
|
||||
public StreamingSockJsSession createSession(String sessionId, WebSocketHandler handler) {
|
||||
Assert.notNull(getSockJsConfig(), "This transport requires SockJsConfiguration");
|
||||
Assert.state(getSockJsConfig() != null, "This transport requires SockJsConfiguration");
|
||||
|
||||
return new StreamingSockJsSession(sessionId, getSockJsConfig(), handler) {
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,7 @@
|
|||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.springframework.web.socket.sockjs.transport;
|
||||
|
||||
import java.io.IOException;
|
||||
|
|
@ -22,7 +23,6 @@ import org.springframework.http.server.ServerHttpRequest;
|
|||
import org.springframework.web.socket.sockjs.TransportHandler;
|
||||
import org.springframework.web.socket.sockjs.TransportType;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link TransportHandler} that receives messages over HTTP.
|
||||
*
|
||||
|
|
@ -30,7 +30,6 @@ import org.springframework.web.socket.sockjs.TransportType;
|
|||
*/
|
||||
public class XhrTransportHandler extends AbstractHttpReceivingTransportHandler {
|
||||
|
||||
|
||||
@Override
|
||||
public TransportType getTransportType() {
|
||||
return TransportType.XHR_SEND;
|
||||
|
|
|
|||
|
|
@ -18,9 +18,8 @@
|
|||
* Server-side support for SockJS transports including
|
||||
* {@link org.springframework.web.socket.sockjs.TransportHandler} implementations
|
||||
* for processing incoming requests and their
|
||||
* {@link org.springframework.sockjs.SockJsSession} counterparts for
|
||||
* {@link org.springframework.web.socket.sockjs.AbstractSockJsSession session} counterparts for
|
||||
* sending messages over the various transports.
|
||||
*
|
||||
*/
|
||||
package org.springframework.web.socket.sockjs.transport;
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ import org.springframework.util.Assert;
|
|||
* Instantiates a target handler through a Spring {@link BeanFactory} and also provides
|
||||
* an equivalent destroy method. Mainly for internal use to assist with initializing and
|
||||
* destroying handlers with per-connection lifecycle.
|
||||
*
|
||||
*
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
*/
|
||||
|
|
@ -43,7 +43,7 @@ public class BeanCreatingHandlerProvider<T> implements BeanFactoryAware {
|
|||
|
||||
|
||||
public BeanCreatingHandlerProvider(Class<? extends T> handlerType) {
|
||||
Assert.notNull(handlerType, "handlerType is required");
|
||||
Assert.notNull(handlerType, "handlerType must not be null");
|
||||
this.handlerType = handlerType;
|
||||
}
|
||||
|
||||
|
|
@ -83,7 +83,7 @@ public class BeanCreatingHandlerProvider<T> implements BeanFactoryAware {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "BeanCreatingHandlerProvider [handlerClass=" + handlerType + "]";
|
||||
return "BeanCreatingHandlerProvider [handlerClass=" + this.handlerType + "]";
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import org.springframework.web.socket.WebSocketHandler;
|
|||
import org.springframework.web.socket.WebSocketMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
|
||||
/**
|
||||
* An exception handling {@link WebSocketHandlerDecorator}. Traps all {@link Throwable}
|
||||
* instances that escape from the decorated handler and closes the session with
|
||||
|
|
@ -34,13 +33,14 @@ import org.springframework.web.socket.WebSocketSession;
|
|||
*/
|
||||
public class ExceptionWebSocketHandlerDecorator extends WebSocketHandlerDecorator {
|
||||
|
||||
private Log logger = LogFactory.getLog(ExceptionWebSocketHandlerDecorator.class);
|
||||
private final Log logger = LogFactory.getLog(ExceptionWebSocketHandlerDecorator.class);
|
||||
|
||||
|
||||
public ExceptionWebSocketHandlerDecorator(WebSocketHandler delegate) {
|
||||
super(delegate);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void afterConnectionEstablished(WebSocketSession session) {
|
||||
try {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import org.springframework.web.socket.WebSocketHandler;
|
|||
import org.springframework.web.socket.WebSocketMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link WebSocketHandlerDecorator} that adds logging to WebSocket lifecycle events.
|
||||
*
|
||||
|
|
@ -32,7 +31,7 @@ import org.springframework.web.socket.WebSocketSession;
|
|||
*/
|
||||
public class LoggingWebSocketHandlerDecorator extends WebSocketHandlerDecorator {
|
||||
|
||||
private Log logger = LogFactory.getLog(LoggingWebSocketHandlerDecorator.class);
|
||||
private final Log logger = LogFactory.getLog(LoggingWebSocketHandlerDecorator.class);
|
||||
|
||||
|
||||
public LoggingWebSocketHandlerDecorator(WebSocketHandler delegate) {
|
||||
|
|
|
|||
|
|
@ -22,7 +22,6 @@ import org.springframework.web.socket.WebSocketHandler;
|
|||
import org.springframework.web.socket.WebSocketMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
|
||||
/**
|
||||
* @author Rossen Stoyanchev
|
||||
* @since 4.0
|
||||
|
|
@ -33,7 +32,7 @@ public class WebSocketHandlerDecorator implements WebSocketHandler {
|
|||
|
||||
|
||||
public WebSocketHandlerDecorator(WebSocketHandler delegate) {
|
||||
Assert.notNull(delegate, "delegate is required");
|
||||
Assert.notNull(delegate, "delegate must not be null");
|
||||
this.delegate = delegate;
|
||||
}
|
||||
|
||||
|
|
@ -43,7 +42,7 @@ public class WebSocketHandlerDecorator implements WebSocketHandler {
|
|||
}
|
||||
|
||||
public WebSocketHandler getLastHandler() {
|
||||
WebSocketHandler result = delegate;
|
||||
WebSocketHandler result = this.delegate;
|
||||
while (result instanceof WebSocketHandlerDecorator) {
|
||||
result = ((WebSocketHandlerDecorator) result).getDelegate();
|
||||
}
|
||||
|
|
@ -75,7 +74,6 @@ public class WebSocketHandlerDecorator implements WebSocketHandler {
|
|||
return this.delegate.supportsPartialMessages();
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return getClass().getSimpleName() + " [delegate=" + this.delegate + "]";
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import org.springframework.http.server.ServletServerHttpResponse;
|
|||
import org.springframework.mock.web.test.MockHttpServletRequest;
|
||||
import org.springframework.mock.web.test.MockHttpServletResponse;
|
||||
|
||||
|
||||
/**
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -24,7 +24,6 @@ import org.springframework.web.socket.WebSocketHandler;
|
|||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
|
||||
/**
|
||||
* Test fixture for {@link JettyWebSocketListenerAdapter}.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ import static org.junit.Assert.*;
|
|||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
|
||||
/**
|
||||
* Test fixture for {@link StandardEndpointAdapter}.
|
||||
*
|
||||
|
|
@ -52,30 +51,30 @@ public class StandardEndpointAdapterTests {
|
|||
this.session = mock(Session.class);
|
||||
this.webSocketHandler = mock(WebSocketHandler.class);
|
||||
this.webSocketSession = new StandardWebSocketSessionAdapter();
|
||||
this.adapter = new StandardEndpointAdapter(webSocketHandler, webSocketSession);
|
||||
this.adapter = new StandardEndpointAdapter(this.webSocketHandler, this.webSocketSession);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onOpen() throws Throwable {
|
||||
this.adapter.onOpen(session, null);
|
||||
this.adapter.onOpen(this.session, null);
|
||||
|
||||
verify(this.webSocketHandler).afterConnectionEstablished(this.webSocketSession);
|
||||
verify(session, atLeast(2)).addMessageHandler(any(MessageHandler.Whole.class));
|
||||
verify(this.session, atLeast(2)).addMessageHandler(any(MessageHandler.Whole.class));
|
||||
|
||||
when(session.getId()).thenReturn("123");
|
||||
when(this.session.getId()).thenReturn("123");
|
||||
assertEquals("123", this.webSocketSession.getId());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onClose() throws Throwable {
|
||||
this.adapter.onClose(session, new CloseReason(CloseCodes.NORMAL_CLOSURE, "reason"));
|
||||
this.adapter.onClose(this.session, new CloseReason(CloseCodes.NORMAL_CLOSURE, "reason"));
|
||||
verify(this.webSocketHandler).afterConnectionClosed(this.webSocketSession, CloseStatus.NORMAL.withReason("reason"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void onError() throws Throwable {
|
||||
Exception exception = new Exception();
|
||||
this.adapter.onError(session, exception);
|
||||
this.adapter.onError(this.session, exception);
|
||||
verify(this.webSocketHandler).handleTransportError(this.webSocketSession, exception);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ import org.springframework.web.socket.support.WebSocketHandlerDecorator;
|
|||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
|
||||
/**
|
||||
* Test fixture for {@link WebSocketConnectionManager}.
|
||||
*
|
||||
|
|
@ -41,7 +40,6 @@ import static org.mockito.Mockito.*;
|
|||
*/
|
||||
public class WebSocketConnectionManagerTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void openConnection() throws Exception {
|
||||
|
||||
|
|
|
|||
|
|
@ -38,7 +38,6 @@ import org.springframework.web.socket.adapter.WebSocketHandlerAdapter;
|
|||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
|
||||
/**
|
||||
* Test fixture for {@link StandardWebSocketClient}.
|
||||
*
|
||||
|
|
@ -46,7 +45,6 @@ import static org.mockito.Mockito.*;
|
|||
*/
|
||||
public class StandardWebSocketClientTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void doHandshake() throws Exception {
|
||||
|
||||
|
|
|
|||
|
|
@ -31,7 +31,6 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationCon
|
|||
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
|
||||
/**
|
||||
* Test fixture for {@link ServerEndpointExporter}.
|
||||
*
|
||||
|
|
@ -51,7 +50,7 @@ public class ServerEndpointExporterTests {
|
|||
this.serverContainer = mock(ServerContainer.class);
|
||||
|
||||
MockServletContext servletContext = new MockServletContext();
|
||||
servletContext.setAttribute("javax.websocket.server.ServerContainer", serverContainer);
|
||||
servletContext.setAttribute("javax.websocket.server.ServerContainer", this.serverContainer);
|
||||
|
||||
this.webAppContext = new AnnotationConfigWebApplicationContext();
|
||||
this.webAppContext.register(Config.class);
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import org.springframework.context.annotation.Configuration;
|
|||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
||||
/**
|
||||
* Test fixture for {@link ServerEndpointRegistration}.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -32,10 +32,8 @@ import org.springframework.web.context.support.AnnotationConfigWebApplicationCon
|
|||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
||||
public class SpringConfiguratorTests {
|
||||
|
||||
|
||||
private MockServletContext servletContext;
|
||||
|
||||
private ContextLoader contextLoader;
|
||||
|
|
@ -50,7 +48,7 @@ public class SpringConfiguratorTests {
|
|||
this.webAppContext = new AnnotationConfigWebApplicationContext();
|
||||
this.webAppContext.register(Config.class);
|
||||
|
||||
this.contextLoader = new ContextLoader(webAppContext);
|
||||
this.contextLoader = new ContextLoader(this.webAppContext);
|
||||
this.contextLoader.initWebApplicationContext(this.servletContext);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -180,7 +180,7 @@ public class AbstractSockJsServiceTests extends AbstractHttpRequestTests {
|
|||
assertTrue(this.servletResponse.getContentAsString().startsWith("<!DOCTYPE html>\n"));
|
||||
assertEquals(496, this.servletResponse.getContentLength());
|
||||
assertEquals("public, max-age=31536000", this.response.getHeaders().getCacheControl());
|
||||
assertEquals("\"0da1ed070012f304e47b83c81c48ad620\"", response.getHeaders().getETag());
|
||||
assertEquals("\"0da1ed070012f304e47b83c81c48ad620\"", this.response.getHeaders().getETag());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
|||
|
|
@ -29,7 +29,6 @@ import static org.junit.Assert.*;
|
|||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
|
||||
/**
|
||||
* Test fixture for {@link AbstractSockJsSession}.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import org.springframework.web.socket.WebSocketHandler;
|
|||
import static org.junit.Assert.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
|
||||
/**
|
||||
* Base class for {@link AbstractSockJsSession} classes.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ package org.springframework.web.socket.sockjs;
|
|||
import org.springframework.scheduling.TaskScheduler;
|
||||
import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler;
|
||||
|
||||
|
||||
/**
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
|
|
@ -34,7 +33,7 @@ public class StubSockJsConfig implements SockJsConfiguration {
|
|||
|
||||
@Override
|
||||
public int getStreamBytesLimit() {
|
||||
return streamBytesLimit;
|
||||
return this.streamBytesLimit;
|
||||
}
|
||||
|
||||
public void setStreamBytesLimit(int streamBytesLimit) {
|
||||
|
|
@ -43,7 +42,7 @@ public class StubSockJsConfig implements SockJsConfiguration {
|
|||
|
||||
@Override
|
||||
public long getHeartbeatTime() {
|
||||
return heartbeatTime;
|
||||
return this.heartbeatTime;
|
||||
}
|
||||
|
||||
public void setHeartbeatTime(long heartbeatTime) {
|
||||
|
|
@ -52,7 +51,7 @@ public class StubSockJsConfig implements SockJsConfiguration {
|
|||
|
||||
@Override
|
||||
public TaskScheduler getTaskScheduler() {
|
||||
return taskScheduler;
|
||||
return this.taskScheduler;
|
||||
}
|
||||
|
||||
public void setTaskScheduler(TaskScheduler taskScheduler) {
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ import java.util.List;
|
|||
import org.springframework.web.socket.CloseStatus;
|
||||
import org.springframework.web.socket.WebSocketHandler;
|
||||
|
||||
|
||||
/**
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
|
|
@ -95,7 +94,7 @@ public class TestSockJsSession extends AbstractSockJsSession {
|
|||
protected void writeFrameInternal(SockJsFrame frame) throws Exception {
|
||||
this.sockJsFramesWritten.add(frame);
|
||||
if (this.exceptionOnWriteFrame != null) {
|
||||
throw exceptionOnWriteFrame;
|
||||
throw this.exceptionOnWriteFrame;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -20,13 +20,11 @@ import org.junit.Test;
|
|||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
||||
/**
|
||||
* @author Rossen Stoyanchev
|
||||
*/
|
||||
public class TransportTypeTests {
|
||||
|
||||
|
||||
@Test
|
||||
public void testFromValue() {
|
||||
assertEquals(TransportType.WEBSOCKET, TransportType.fromValue("websocket"));
|
||||
|
|
|
|||
|
|
@ -48,7 +48,6 @@ import static org.mockito.Mockito.*;
|
|||
*/
|
||||
public class DefaultSockJsServiceTests extends AbstractHttpRequestTests {
|
||||
|
||||
|
||||
@Override
|
||||
@Before
|
||||
public void setUp() {
|
||||
|
|
|
|||
|
|
@ -62,24 +62,24 @@ public class HttpSendingTransportHandlerTests extends AbstractHttpRequestTests
|
|||
public void handleRequestXhr() throws Exception {
|
||||
|
||||
XhrPollingTransportHandler transportHandler = new XhrPollingTransportHandler();
|
||||
transportHandler.setSockJsConfiguration(sockJsConfig);
|
||||
transportHandler.setSockJsConfiguration(this.sockJsConfig);
|
||||
|
||||
AbstractSockJsSession session = transportHandler.createSession("1", webSocketHandler);
|
||||
transportHandler.handleRequest(request, response, webSocketHandler, session);
|
||||
AbstractSockJsSession session = transportHandler.createSession("1", this.webSocketHandler);
|
||||
transportHandler.handleRequest(this.request, this.response, this.webSocketHandler, session);
|
||||
|
||||
assertEquals("application/javascript;charset=UTF-8", this.response.getHeaders().getContentType().toString());
|
||||
assertEquals("o\n", this.servletResponse.getContentAsString());
|
||||
assertFalse("Polling request should complete after open frame", this.servletRequest.isAsyncStarted());
|
||||
verify(webSocketHandler).afterConnectionEstablished(session);
|
||||
verify(this.webSocketHandler).afterConnectionEstablished(session);
|
||||
|
||||
resetResponse();
|
||||
transportHandler.handleRequest(request, response, webSocketHandler, session);
|
||||
transportHandler.handleRequest(this.request, this.response, this.webSocketHandler, session);
|
||||
|
||||
assertTrue("Polling request should remain open", this.servletRequest.isAsyncStarted());
|
||||
verify(this.taskScheduler).schedule(any(Runnable.class), any(Date.class));
|
||||
|
||||
resetRequestAndResponse();
|
||||
transportHandler.handleRequest(request, response, webSocketHandler, session);
|
||||
transportHandler.handleRequest(this.request, this.response, this.webSocketHandler, session);
|
||||
|
||||
assertFalse("Request should have been rejected", this.servletRequest.isAsyncStarted());
|
||||
assertEquals("c[2010,\"Another connection still open\"]\n", this.servletResponse.getContentAsString());
|
||||
|
|
@ -89,70 +89,70 @@ public class HttpSendingTransportHandlerTests extends AbstractHttpRequestTests
|
|||
public void jsonpTransport() throws Exception {
|
||||
|
||||
JsonpPollingTransportHandler transportHandler = new JsonpPollingTransportHandler();
|
||||
transportHandler.setSockJsConfiguration(sockJsConfig);
|
||||
PollingSockJsSession session = transportHandler.createSession("1", webSocketHandler);
|
||||
transportHandler.setSockJsConfiguration(this.sockJsConfig);
|
||||
PollingSockJsSession session = transportHandler.createSession("1", this.webSocketHandler);
|
||||
|
||||
transportHandler.handleRequest(request, response, webSocketHandler, session);
|
||||
transportHandler.handleRequest(this.request, this.response, this.webSocketHandler, session);
|
||||
|
||||
assertEquals(500, this.servletResponse.getStatus());
|
||||
assertEquals("\"callback\" parameter required", this.servletResponse.getContentAsString());
|
||||
|
||||
resetRequestAndResponse();
|
||||
this.servletRequest.addParameter("c", "callback");
|
||||
transportHandler.handleRequest(request, response, webSocketHandler, session);
|
||||
transportHandler.handleRequest(this.request, this.response, this.webSocketHandler, session);
|
||||
|
||||
assertEquals("application/javascript;charset=UTF-8", this.response.getHeaders().getContentType().toString());
|
||||
assertFalse("Polling request should complete after open frame", this.servletRequest.isAsyncStarted());
|
||||
verify(webSocketHandler).afterConnectionEstablished(session);
|
||||
verify(this.webSocketHandler).afterConnectionEstablished(session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void handleRequestXhrStreaming() throws Exception {
|
||||
|
||||
XhrStreamingTransportHandler transportHandler = new XhrStreamingTransportHandler();
|
||||
transportHandler.setSockJsConfiguration(sockJsConfig);
|
||||
AbstractSockJsSession session = transportHandler.createSession("1", webSocketHandler);
|
||||
transportHandler.setSockJsConfiguration(this.sockJsConfig);
|
||||
AbstractSockJsSession session = transportHandler.createSession("1", this.webSocketHandler);
|
||||
|
||||
transportHandler.handleRequest(request, response, webSocketHandler, session);
|
||||
transportHandler.handleRequest(this.request, this.response, this.webSocketHandler, session);
|
||||
|
||||
assertEquals("application/javascript;charset=UTF-8", this.response.getHeaders().getContentType().toString());
|
||||
assertTrue("Streaming request not started", this.servletRequest.isAsyncStarted());
|
||||
verify(webSocketHandler).afterConnectionEstablished(session);
|
||||
verify(this.webSocketHandler).afterConnectionEstablished(session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void htmlFileTransport() throws Exception {
|
||||
|
||||
HtmlFileTransportHandler transportHandler = new HtmlFileTransportHandler();
|
||||
transportHandler.setSockJsConfiguration(sockJsConfig);
|
||||
StreamingSockJsSession session = transportHandler.createSession("1", webSocketHandler);
|
||||
transportHandler.setSockJsConfiguration(this.sockJsConfig);
|
||||
StreamingSockJsSession session = transportHandler.createSession("1", this.webSocketHandler);
|
||||
|
||||
transportHandler.handleRequest(request, response, webSocketHandler, session);
|
||||
transportHandler.handleRequest(this.request, this.response, this.webSocketHandler, session);
|
||||
|
||||
assertEquals(500, this.servletResponse.getStatus());
|
||||
assertEquals("\"callback\" parameter required", this.servletResponse.getContentAsString());
|
||||
|
||||
resetRequestAndResponse();
|
||||
this.servletRequest.addParameter("c", "callback");
|
||||
transportHandler.handleRequest(request, response, webSocketHandler, session);
|
||||
transportHandler.handleRequest(this.request, this.response, this.webSocketHandler, session);
|
||||
|
||||
assertEquals("text/html;charset=UTF-8", this.response.getHeaders().getContentType().toString());
|
||||
assertTrue("Streaming request not started", this.servletRequest.isAsyncStarted());
|
||||
verify(webSocketHandler).afterConnectionEstablished(session);
|
||||
verify(this.webSocketHandler).afterConnectionEstablished(session);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void eventSourceTransport() throws Exception {
|
||||
|
||||
EventSourceTransportHandler transportHandler = new EventSourceTransportHandler();
|
||||
transportHandler.setSockJsConfiguration(sockJsConfig);
|
||||
StreamingSockJsSession session = transportHandler.createSession("1", webSocketHandler);
|
||||
transportHandler.setSockJsConfiguration(this.sockJsConfig);
|
||||
StreamingSockJsSession session = transportHandler.createSession("1", this.webSocketHandler);
|
||||
|
||||
transportHandler.handleRequest(request, response, webSocketHandler, session);
|
||||
transportHandler.handleRequest(this.request, this.response, this.webSocketHandler, session);
|
||||
|
||||
assertEquals("text/event-stream;charset=UTF-8", this.response.getHeaders().getContentType().toString());
|
||||
assertTrue("Streaming request not started", this.servletRequest.isAsyncStarted());
|
||||
verify(webSocketHandler).afterConnectionEstablished(session);
|
||||
verify(this.webSocketHandler).afterConnectionEstablished(session);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -162,23 +162,23 @@ public class HttpSendingTransportHandlerTests extends AbstractHttpRequestTests
|
|||
|
||||
SockJsFrame frame = SockJsFrame.openFrame();
|
||||
|
||||
FrameFormat format = new XhrPollingTransportHandler().getFrameFormat(request);
|
||||
FrameFormat format = new XhrPollingTransportHandler().getFrameFormat(this.request);
|
||||
SockJsFrame formatted = format.format(frame);
|
||||
assertEquals(frame.getContent() + "\n", formatted.getContent());
|
||||
|
||||
format = new XhrStreamingTransportHandler().getFrameFormat(request);
|
||||
format = new XhrStreamingTransportHandler().getFrameFormat(this.request);
|
||||
formatted = format.format(frame);
|
||||
assertEquals(frame.getContent() + "\n", formatted.getContent());
|
||||
|
||||
format = new HtmlFileTransportHandler().getFrameFormat(request);
|
||||
format = new HtmlFileTransportHandler().getFrameFormat(this.request);
|
||||
formatted = format.format(frame);
|
||||
assertEquals("<script>\np(\"" + frame.getContent() + "\");\n</script>\r\n", formatted.getContent());
|
||||
|
||||
format = new EventSourceTransportHandler().getFrameFormat(request);
|
||||
format = new EventSourceTransportHandler().getFrameFormat(this.request);
|
||||
formatted = format.format(frame);
|
||||
assertEquals("data: " + frame.getContent() + "\r\n\r\n", formatted.getContent());
|
||||
|
||||
format = new JsonpPollingTransportHandler().getFrameFormat(request);
|
||||
format = new JsonpPollingTransportHandler().getFrameFormat(this.request);
|
||||
formatted = format.format(frame);
|
||||
assertEquals("callback(\"" + frame.getContent() + "\");\r\n", formatted.getContent());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ import static org.junit.Assert.*;
|
|||
import static org.mockito.Matchers.*;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
|
||||
/**
|
||||
* Test fixture for {@link WebSocketServerSockJsSession}.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -26,8 +26,6 @@ import org.springframework.context.annotation.Configuration;
|
|||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Test fixture for {@link BeanCreatingHandlerProvider}.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ import org.springframework.web.socket.CloseStatus;
|
|||
import org.springframework.web.socket.WebSocketMessage;
|
||||
import org.springframework.web.socket.WebSocketSession;
|
||||
|
||||
|
||||
/**
|
||||
* A {@link WebSocketSession} for use in tests.
|
||||
*
|
||||
|
|
@ -58,7 +57,7 @@ public class TestWebSocketSession implements WebSocketSession {
|
|||
*/
|
||||
@Override
|
||||
public String getId() {
|
||||
return id;
|
||||
return this.id;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -73,7 +72,7 @@ public class TestWebSocketSession implements WebSocketSession {
|
|||
*/
|
||||
@Override
|
||||
public URI getUri() {
|
||||
return uri;
|
||||
return this.uri;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -88,7 +87,7 @@ public class TestWebSocketSession implements WebSocketSession {
|
|||
*/
|
||||
@Override
|
||||
public boolean isSecure() {
|
||||
return secure;
|
||||
return this.secure;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -103,7 +102,7 @@ public class TestWebSocketSession implements WebSocketSession {
|
|||
*/
|
||||
@Override
|
||||
public Principal getPrincipal() {
|
||||
return principal;
|
||||
return this.principal;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -118,7 +117,7 @@ public class TestWebSocketSession implements WebSocketSession {
|
|||
*/
|
||||
@Override
|
||||
public String getRemoteHostName() {
|
||||
return remoteHostName;
|
||||
return this.remoteHostName;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -133,7 +132,7 @@ public class TestWebSocketSession implements WebSocketSession {
|
|||
*/
|
||||
@Override
|
||||
public String getRemoteAddress() {
|
||||
return remoteAddress;
|
||||
return this.remoteAddress;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -148,7 +147,7 @@ public class TestWebSocketSession implements WebSocketSession {
|
|||
*/
|
||||
@Override
|
||||
public boolean isOpen() {
|
||||
return open;
|
||||
return this.open;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import org.springframework.web.socket.adapter.WebSocketHandlerAdapter;
|
|||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
|
||||
/**
|
||||
* Test fixture for {@link WebSocketHandlerDecorator}.
|
||||
*
|
||||
|
|
|
|||
Loading…
Reference in New Issue