diff --git a/build.gradle b/build.gradle index ea959552c8e..7db372c12cb 100644 --- a/build.gradle +++ b/build.gradle @@ -515,7 +515,6 @@ project("spring-websocket") { compile(project(":spring-core")) compile(project(":spring-context")) compile(project(":spring-web")) - optional(project(":spring-webmvc")) optional("org.apache.tomcat:tomcat-servlet-api:8.0-SNAPSHOT") // TODO: replace with "javax.servlet:javax.servlet-api" optional("org.apache.tomcat:tomcat-websocket-api:8.0-SNAPSHOT") // TODO: replace with "javax.websocket:javax.websocket-api" 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 21dc2150973..6331c003c6f 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/WebSocketHandler.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/WebSocketHandler.java @@ -21,7 +21,7 @@ package org.springframework.websocket; * *

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(101)} by default. + * 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.websocket.support.ExceptionWebSocketHandlerDecorator ExceptionWebSocketHandlerDecorator}, * which can be customized or replaced by decorating the {@link WebSocketHandler} with a diff --git a/spring-websocket/src/main/java/org/springframework/websocket/client/AbstractWebSocketConnectionManager.java b/spring-websocket/src/main/java/org/springframework/websocket/client/ConnectionManagerSupport.java similarity index 96% rename from spring-websocket/src/main/java/org/springframework/websocket/client/AbstractWebSocketConnectionManager.java rename to spring-websocket/src/main/java/org/springframework/websocket/client/ConnectionManagerSupport.java index a67a9e7350e..abf19ce4917 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/client/AbstractWebSocketConnectionManager.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/client/ConnectionManagerSupport.java @@ -31,7 +31,7 @@ import org.springframework.web.util.UriComponentsBuilder; * @author Rossen Stoyanchev * @since 4.0 */ -public abstract class AbstractWebSocketConnectionManager implements SmartLifecycle { +public abstract class ConnectionManagerSupport implements SmartLifecycle { protected final Log logger = LogFactory.getLog(getClass()); @@ -49,7 +49,7 @@ public abstract class AbstractWebSocketConnectionManager implements SmartLifecyc private final Object lifecycleMonitor = new Object(); - public AbstractWebSocketConnectionManager(String uriTemplate, Object... uriVariables) { + public ConnectionManagerSupport(String uriTemplate, Object... uriVariables) { this.uri = UriComponentsBuilder.fromUriString(uriTemplate).buildAndExpand(uriVariables).encode().toUri(); } 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 09c0d06cf2a..07edf7e1e3d 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 @@ -31,7 +31,7 @@ import org.springframework.websocket.support.LoggingWebSocketHandlerDecorator; * @author Rossen Stoyanchev * @since 4.0 */ -public class WebSocketConnectionManager extends AbstractWebSocketConnectionManager { +public class WebSocketConnectionManager extends ConnectionManagerSupport { private final WebSocketClient client; diff --git a/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/AnnotatedEndpointConnectionManager.java b/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/AnnotatedEndpointConnectionManager.java index 26747440138..6e9267f507b 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/AnnotatedEndpointConnectionManager.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/AnnotatedEndpointConnectionManager.java @@ -16,23 +16,29 @@ package org.springframework.websocket.client.endpoint; +import javax.websocket.ContainerProvider; import javax.websocket.Session; +import javax.websocket.WebSocketContainer; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; +import org.springframework.websocket.client.ConnectionManagerSupport; import org.springframework.websocket.support.BeanCreatingHandlerProvider; /** * @author Rossen Stoyanchev * @since 4.0 */ -public class AnnotatedEndpointConnectionManager extends EndpointConnectionManagerSupport - implements BeanFactoryAware { +public class AnnotatedEndpointConnectionManager extends ConnectionManagerSupport implements BeanFactoryAware { + + private final Object endpoint; private final BeanCreatingHandlerProvider endpointProvider; - private final Object endpoint; + private WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer(); + + private Session session; public AnnotatedEndpointConnectionManager(Object endpoint, String uriTemplate, Object... uriVariables) { @@ -48,6 +54,14 @@ public class AnnotatedEndpointConnectionManager extends EndpointConnectionManage } + public void setWebSocketContainer(WebSocketContainer webSocketContainer) { + this.webSocketContainer = webSocketContainer; + } + + public WebSocketContainer getWebSocketContainer() { + return this.webSocketContainer; + } + @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { if (this.endpointProvider != null) { @@ -58,8 +72,24 @@ public class AnnotatedEndpointConnectionManager extends EndpointConnectionManage @Override protected void openConnection() throws Exception { Object endpoint = (this.endpoint != null) ? this.endpoint : this.endpointProvider.getHandler(); - Session session = getWebSocketContainer().connectToServer(endpoint, getUri()); - updateSession(session); + this.session = this.webSocketContainer.connectToServer(endpoint, getUri()); + } + + @Override + protected void closeConnection() throws Exception { + try { + if (isConnected()) { + this.session.close(); + } + } + finally { + this.session = null; + } + } + + @Override + protected boolean isConnected() { + return ((this.session != null) && this.session.isOpen()); } } diff --git a/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/EndpointConnectionManager.java b/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/EndpointConnectionManager.java index 3c2dcdefa7b..9e96b160f2b 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/EndpointConnectionManager.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/EndpointConnectionManager.java @@ -21,29 +21,36 @@ import java.util.List; import javax.websocket.ClientEndpointConfig; import javax.websocket.ClientEndpointConfig.Configurator; +import javax.websocket.ContainerProvider; import javax.websocket.Decoder; import javax.websocket.Encoder; import javax.websocket.Endpoint; import javax.websocket.Extension; import javax.websocket.Session; +import javax.websocket.WebSocketContainer; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.util.Assert; +import org.springframework.websocket.client.ConnectionManagerSupport; import org.springframework.websocket.support.BeanCreatingHandlerProvider; /** * @author Rossen Stoyanchev * @since 4.0 */ -public class EndpointConnectionManager extends EndpointConnectionManagerSupport implements BeanFactoryAware { +public class EndpointConnectionManager extends ConnectionManagerSupport implements BeanFactoryAware { - private final ClientEndpointConfig.Builder configBuilder = ClientEndpointConfig.Builder.create(); + private final Endpoint endpoint; private final BeanCreatingHandlerProvider endpointProvider; - private final Endpoint endpoint; + private final ClientEndpointConfig.Builder configBuilder = ClientEndpointConfig.Builder.create(); + + private WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer(); + + private Session session; public EndpointConnectionManager(Endpoint endpoint, String uriTemplate, Object... uriVariables) { @@ -81,6 +88,14 @@ public class EndpointConnectionManager extends EndpointConnectionManagerSupport this.configBuilder.configurator(configurator); } + public void setWebSocketContainer(WebSocketContainer webSocketContainer) { + this.webSocketContainer = webSocketContainer; + } + + public WebSocketContainer getWebSocketContainer() { + return this.webSocketContainer; + } + @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { if (this.endpointProvider != null) { @@ -92,8 +107,24 @@ public class EndpointConnectionManager extends EndpointConnectionManagerSupport protected void openConnection() throws Exception { Endpoint endpoint = (this.endpoint != null) ? this.endpoint : this.endpointProvider.getHandler(); ClientEndpointConfig endpointConfig = this.configBuilder.build(); - Session session = getWebSocketContainer().connectToServer(endpoint, endpointConfig, getUri()); - updateSession(session); + this.session = getWebSocketContainer().connectToServer(endpoint, endpointConfig, getUri()); + } + + @Override + protected void closeConnection() throws Exception { + try { + if (isConnected()) { + this.session.close(); + } + } + finally { + this.session = null; + } + } + + @Override + protected boolean isConnected() { + return ((this.session != null) && this.session.isOpen()); } } diff --git a/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/EndpointConnectionManagerSupport.java b/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/EndpointConnectionManagerSupport.java deleted file mode 100644 index dfdee7c9666..00000000000 --- a/spring-websocket/src/main/java/org/springframework/websocket/client/endpoint/EndpointConnectionManagerSupport.java +++ /dev/null @@ -1,70 +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.client.endpoint; - -import javax.websocket.ContainerProvider; -import javax.websocket.Session; -import javax.websocket.WebSocketContainer; - -import org.springframework.websocket.client.AbstractWebSocketConnectionManager; - -/** - * @author Rossen Stoyanchev - * @since 4.0 - */ -public abstract class EndpointConnectionManagerSupport extends AbstractWebSocketConnectionManager { - - private WebSocketContainer webSocketContainer = ContainerProvider.getWebSocketContainer(); - - private Session session; - - - public EndpointConnectionManagerSupport(String uriTemplate, Object... uriVariables) { - super(uriTemplate, uriVariables); - } - - - public void setWebSocketContainer(WebSocketContainer webSocketContainer) { - this.webSocketContainer = webSocketContainer; - } - - public WebSocketContainer getWebSocketContainer() { - return this.webSocketContainer; - } - - protected void updateSession(Session session) { - this.session = session; - } - - @Override - protected void closeConnection() throws Exception { - try { - if (isConnected()) { - this.session.close(); - } - } - finally { - this.session = null; - } - } - - @Override - protected boolean isConnected() { - return ((this.session != null) && this.session.isOpen()); - } - -} 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 5e658feccc6..f4d4b90d2a8 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 @@ -44,7 +44,7 @@ import org.springframework.websocket.WebSocketHandler; *

* 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. + * Currently available are implementations for Tomcat and GlassFish. * * @author Rossen Stoyanchev * @since 4.0 @@ -218,7 +218,7 @@ public class DefaultHandshakeHandler implements HandshakeHandler { private static final boolean tomcatWebSocketPresent = ClassUtils.isPresent( "org.apache.tomcat.websocket.server.WsHttpUpgradeHandler", DefaultHandshakeHandler.class.getClassLoader()); - private static final boolean glassfishWebSocketPresent = ClassUtils.isPresent( + private static final boolean glassFishWebSocketPresent = ClassUtils.isPresent( "org.glassfish.tyrus.servlet.TyrusHttpUpgradeHandler", DefaultHandshakeHandler.class.getClassLoader()); private static final boolean jettyWebSocketPresent = ClassUtils.isPresent( @@ -229,8 +229,8 @@ public class DefaultHandshakeHandler implements HandshakeHandler { if (tomcatWebSocketPresent) { className = "org.springframework.websocket.server.support.TomcatRequestUpgradeStrategy"; } - else if (glassfishWebSocketPresent) { - className = "org.springframework.websocket.server.support.GlassfishRequestUpgradeStrategy"; + else if (glassFishWebSocketPresent) { + className = "org.springframework.websocket.server.support.GlassFishRequestUpgradeStrategy"; } else if (jettyWebSocketPresent) { className = "org.springframework.websocket.server.support.JettyRequestUpgradeStrategy"; diff --git a/spring-websocket/src/main/java/org/springframework/websocket/server/support/GlassfishRequestUpgradeStrategy.java b/spring-websocket/src/main/java/org/springframework/websocket/server/support/GlassFishRequestUpgradeStrategy.java similarity index 95% rename from spring-websocket/src/main/java/org/springframework/websocket/server/support/GlassfishRequestUpgradeStrategy.java rename to spring-websocket/src/main/java/org/springframework/websocket/server/support/GlassFishRequestUpgradeStrategy.java index 358813af800..1d25d7e5de8 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/server/support/GlassfishRequestUpgradeStrategy.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/server/support/GlassFishRequestUpgradeStrategy.java @@ -52,13 +52,13 @@ import org.springframework.websocket.server.HandshakeFailureException; import org.springframework.websocket.server.endpoint.EndpointRegistration; /** - * Glassfish support for upgrading an {@link HttpServletRequest} during a WebSocket + * GlassFish support for upgrading an {@link HttpServletRequest} during a WebSocket * handshake. * * @author Rossen Stoyanchev * @since 4.0 */ -public class GlassfishRequestUpgradeStrategy extends AbstractEndpointUpgradeStrategy { +public class GlassFishRequestUpgradeStrategy extends AbstractEndpointUpgradeStrategy { private final static Random random = new Random(); @@ -86,7 +86,7 @@ public class GlassfishRequestUpgradeStrategy extends AbstractEndpointUpgradeStra engine.register(tyrusEndpoint); } catch (DeploymentException ex) { - throw new HandshakeFailureException("Failed to deploy endpoint in Glassfish", ex); + throw new HandshakeFailureException("Failed to deploy endpoint in GlassFish", ex); } try { @@ -140,13 +140,13 @@ public class GlassfishRequestUpgradeStrategy extends AbstractEndpointUpgradeStra private Connection createConnection(TyrusHttpUpgradeHandler handler, HttpServletResponse response) { try { String name = "org.glassfish.tyrus.servlet.ConnectionImpl"; - Class clazz = ClassUtils.forName(name, GlassfishRequestUpgradeStrategy.class.getClassLoader()); + Class clazz = ClassUtils.forName(name, GlassFishRequestUpgradeStrategy.class.getClassLoader()); Constructor constructor = clazz.getDeclaredConstructor(TyrusHttpUpgradeHandler.class, HttpServletResponse.class); ReflectionUtils.makeAccessible(constructor); return (Connection) constructor.newInstance(handler, response); } catch (Exception ex) { - throw new IllegalStateException("Failed to instantiate Glassfish connection", ex); + throw new IllegalStateException("Failed to instantiate GlassFish connection", ex); } } diff --git a/spring-websocket/src/main/java/org/springframework/websocket/support/PerConnectionWebSocketHandlerProxy.java b/spring-websocket/src/main/java/org/springframework/websocket/support/PerConnectionWebSocketHandler.java similarity index 89% rename from spring-websocket/src/main/java/org/springframework/websocket/support/PerConnectionWebSocketHandlerProxy.java rename to spring-websocket/src/main/java/org/springframework/websocket/support/PerConnectionWebSocketHandler.java index 64ed5c4bec9..53cd3dc08c7 100644 --- a/spring-websocket/src/main/java/org/springframework/websocket/support/PerConnectionWebSocketHandlerProxy.java +++ b/spring-websocket/src/main/java/org/springframework/websocket/support/PerConnectionWebSocketHandler.java @@ -48,23 +48,23 @@ import org.springframework.websocket.WebSocketSession; * @author Rossen Stoyanchev * @since 4.0 */ -public class PerConnectionWebSocketHandlerProxy implements WebSocketHandler, BeanFactoryAware { +public class PerConnectionWebSocketHandler implements WebSocketHandler, BeanFactoryAware { - private Log logger = LogFactory.getLog(PerConnectionWebSocketHandlerProxy.class); + private static final Log logger = LogFactory.getLog(PerConnectionWebSocketHandler.class); private final BeanCreatingHandlerProvider provider; - private Map handlers = + private final Map handlers = new ConcurrentHashMap(); - private boolean streaming; + private final boolean streaming; - public PerConnectionWebSocketHandlerProxy(Class handlerType) { + public PerConnectionWebSocketHandler(Class handlerType) { this(handlerType, false); } - public PerConnectionWebSocketHandlerProxy(Class handlerType, boolean isStreaming) { + public PerConnectionWebSocketHandler(Class handlerType, boolean isStreaming) { this.provider = new BeanCreatingHandlerProvider(handlerType); this.streaming = isStreaming; }