From a9b88d6955ca1877056708417384286c8b75dd8b Mon Sep 17 00:00:00 2001
From: Andy Wilkinson
Date: Tue, 21 Oct 2014 16:02:48 +0100
Subject: [PATCH] Document need for ServerEndpointExporter and show its use in
a sample
Traditionally, a @ServerEndpoint-annotated bean is found by a servlet
container initialiser, however Boot does not run servlet container
initialisers when an embedded container is being used. To be able to use
@ServerEndpoint in a Boot app that uses embedded Tomcat a
ServerEndpointExporter bean must be declared.
This commit updates the documentation to describe this requirement and
also updates the WebSockets sample to illustrate the use of
ServerEndpointExporter. The version of Spring Framework has been updated
to 4.0.8.BUILD-SNAPSHOT. This picks up the fix for SPR-12340.
Closes gh-1722
---
spring-boot-dependencies/pom.xml | 2 +-
spring-boot-docs/src/main/asciidoc/howto.adoc | 20 +++
.../client/SimpleClientWebSocketHandler.java | 7 +-
.../config/SampleWebSocketsApplication.java | 12 ++
.../reverse/ReverseWebSocketEndpoint.java | 33 +++++
.../src/main/resources/static/index.html | 1 +
.../src/main/resources/static/reverse.html | 140 ++++++++++++++++++
.../SampleWebSocketsApplicationTests.java | 56 +++++--
...omContainerWebSocketsApplicationTests.java | 50 +++++--
9 files changed, 293 insertions(+), 28 deletions(-)
create mode 100644 spring-boot-samples/spring-boot-sample-websocket/src/main/java/samples/websocket/reverse/ReverseWebSocketEndpoint.java
create mode 100644 spring-boot-samples/spring-boot-sample-websocket/src/main/resources/static/reverse.html
rename spring-boot-samples/spring-boot-sample-websocket/src/test/java/samples/websocket/{echo => }/SampleWebSocketsApplicationTests.java (63%)
diff --git a/spring-boot-dependencies/pom.xml b/spring-boot-dependencies/pom.xml
index fe7fdc75d9..a205985bb2 100644
--- a/spring-boot-dependencies/pom.xml
+++ b/spring-boot-dependencies/pom.xml
@@ -98,7 +98,7 @@
1.134.7.20.7-groovy-2.0
- 4.0.7.RELEASE
+ 4.0.8.BUILD-SNAPSHOT1.3.6.RELEASE3.0.2.RELEASEDijkstra-SR4
diff --git a/spring-boot-docs/src/main/asciidoc/howto.adoc b/spring-boot-docs/src/main/asciidoc/howto.adoc
index cec330ae72..a967d4931f 100644
--- a/spring-boot-docs/src/main/asciidoc/howto.adoc
+++ b/spring-boot-docs/src/main/asciidoc/howto.adoc
@@ -617,6 +617,26 @@ change the version properties, e.g. for a simple webapp or service:
+[[howto-create-websocket-endpoints-using-serverendpoint]]
+=== Create WebSocket endpoints using @ServerEndpoint
+If you want to use `@ServerEndpoint` in a Spring Boot application that used an embedded
+container, you must declare a single `ServerEndpointExporter` `@Bean`:
+
+[source,java,indent=0,subs="verbatim,quotes,attributes"]
+----
+ @Bean
+ public ServerEndpointExporter serverEndpointExporter() {
+ return new ServerEndpointExporter();
+ }
+----
+
+This bean will register any `@ServerEndpoint` annotated beans with the underlying
+WebSocket container. When deployed to a standalone servlet container this role is
+performed by a servlet container initializer and the `ServerEndpointExporter` bean is
+not required.
+
+
+
[[howto-spring-mvc]]
== Spring MVC
diff --git a/spring-boot-samples/spring-boot-sample-websocket/src/main/java/samples/websocket/client/SimpleClientWebSocketHandler.java b/spring-boot-samples/spring-boot-sample-websocket/src/main/java/samples/websocket/client/SimpleClientWebSocketHandler.java
index 1b3dc4ef89..a3bbfc2f1c 100644
--- a/spring-boot-samples/spring-boot-sample-websocket/src/main/java/samples/websocket/client/SimpleClientWebSocketHandler.java
+++ b/spring-boot-samples/spring-boot-sample-websocket/src/main/java/samples/websocket/client/SimpleClientWebSocketHandler.java
@@ -17,6 +17,7 @@
package samples.websocket.client;
import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -33,11 +34,14 @@ public class SimpleClientWebSocketHandler extends TextWebSocketHandler {
private final CountDownLatch latch;
+ private final AtomicReference messagePayload;
+
@Autowired
public SimpleClientWebSocketHandler(GreetingService greetingService,
- CountDownLatch latch) {
+ CountDownLatch latch, AtomicReference message) {
this.greetingService = greetingService;
this.latch = latch;
+ this.messagePayload = message;
}
@Override
@@ -51,6 +55,7 @@ public class SimpleClientWebSocketHandler extends TextWebSocketHandler {
throws Exception {
this.logger.info("Received: " + message + " (" + this.latch.getCount() + ")");
session.close();
+ this.messagePayload.set(message.getPayload());
this.latch.countDown();
}
diff --git a/spring-boot-samples/spring-boot-sample-websocket/src/main/java/samples/websocket/config/SampleWebSocketsApplication.java b/spring-boot-samples/spring-boot-sample-websocket/src/main/java/samples/websocket/config/SampleWebSocketsApplication.java
index 8d84d2fcd2..7bc9fd37a8 100644
--- a/spring-boot-samples/spring-boot-sample-websocket/src/main/java/samples/websocket/config/SampleWebSocketsApplication.java
+++ b/spring-boot-samples/spring-boot-sample-websocket/src/main/java/samples/websocket/config/SampleWebSocketsApplication.java
@@ -27,12 +27,14 @@ import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;
import org.springframework.web.socket.handler.PerConnectionWebSocketHandler;
+import org.springframework.web.socket.server.standard.ServerEndpointExporter;
import samples.websocket.client.GreetingService;
import samples.websocket.client.SimpleGreetingService;
import samples.websocket.echo.DefaultEchoService;
import samples.websocket.echo.EchoService;
import samples.websocket.echo.EchoWebSocketHandler;
+import samples.websocket.reverse.ReverseWebSocketEndpoint;
import samples.websocket.snake.SnakeWebSocketHandler;
@Configuration
@@ -76,4 +78,14 @@ public class SampleWebSocketsApplication extends SpringBootServletInitializer im
return new PerConnectionWebSocketHandler(SnakeWebSocketHandler.class);
}
+ @Bean
+ public ReverseWebSocketEndpoint reverseWebSocketEndpoint() {
+ return new ReverseWebSocketEndpoint();
+ }
+
+ @Bean
+ public ServerEndpointExporter serverEndpointExporter() {
+ return new ServerEndpointExporter();
+ }
+
}
diff --git a/spring-boot-samples/spring-boot-sample-websocket/src/main/java/samples/websocket/reverse/ReverseWebSocketEndpoint.java b/spring-boot-samples/spring-boot-sample-websocket/src/main/java/samples/websocket/reverse/ReverseWebSocketEndpoint.java
new file mode 100644
index 0000000000..a7802edcd2
--- /dev/null
+++ b/spring-boot-samples/spring-boot-sample-websocket/src/main/java/samples/websocket/reverse/ReverseWebSocketEndpoint.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2012-2014 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 samples.websocket.reverse;
+
+import java.io.IOException;
+
+import javax.websocket.OnMessage;
+import javax.websocket.Session;
+import javax.websocket.server.ServerEndpoint;
+
+@ServerEndpoint("/reverse")
+public class ReverseWebSocketEndpoint {
+
+ @OnMessage
+ public void handleMessage(Session session, String message) throws IOException {
+ session.getBasicRemote().sendText(
+ "Reversed: " + new StringBuilder(message).reverse());
+ }
+}
diff --git a/spring-boot-samples/spring-boot-sample-websocket/src/main/resources/static/index.html b/spring-boot-samples/spring-boot-sample-websocket/src/main/resources/static/index.html
index 39069b15d7..e2b76b6e44 100644
--- a/spring-boot-samples/spring-boot-sample-websocket/src/main/resources/static/index.html
+++ b/spring-boot-samples/spring-boot-sample-websocket/src/main/resources/static/index.html
@@ -25,6 +25,7 @@