Mastering WebSocket Integration in Spring Boot: Javax, WebMVC, WebFlux and More
This article provides a comprehensive guide to integrating WebSocket in Spring Boot, covering the native Javax API, Spring WebMVC and WebFlux approaches, as well as popular third‑party libraries such as Java‑WebSocket, SocketIO and Netty, with detailed configuration steps, code examples, and practical tips.
WebSocket integration options in Spring Boot
javax.websocket (Java EE API)
Spring WebMVC (Servlet‑based)
Spring WebFlux (reactive)
Java‑WebSocket (pure Java library)
Socket.IO (protocol on top of WebSocket)
Netty (asynchronous networking framework)
javax.websocket
Server endpoint
@Component
@ServerEndpoint("/websocket/{type}")
public class JavaxWebSocketServerEndpoint {
@OnOpen
public void onOpen(Session session, EndpointConfig config, @PathParam("type") String type) {
// connection opened
}
@OnClose
public void onClose(Session session, CloseReason reason) {
// connection closed
}
@OnMessage
public void onMessage(Session session, String message) {
// text message
}
@OnMessage
public void onMessage(Session session, PongMessage message) {
// pong message
}
@OnMessage
public void onMessage(Session session, ByteBuffer message) {
// binary message
}
@OnError
public void onError(Session session, Throwable e) {
// error handling
}
}The @ServerEndpoint annotation defines the WebSocket path; dynamic segments are expressed with {}. Lifecycle callbacks are annotated with @OnOpen, @OnClose, @OnMessage (text, binary, pong) and @OnError.
Spring Boot configuration
implementation 'org.springframework.boot:spring-boot-starter-websocket'
@Configuration(proxyBeanMethods = false)
public class JavaxWebSocketConfiguration {
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}Adding the starter and exposing a ServerEndpointExporter enables native Javax WebSocket support.
Ping/Pong
// send ping
session.getAsyncRemote().sendPing(ByteBuffer.allocate(0));
// send pong
session.getAsyncRemote().sendPong(ByteBuffer.allocate(0));Client endpoint
@ClientEndpoint
public class JavaxWebSocketClientEndpoint {
@OnOpen
public void onOpen(Session session) {}
@OnClose
public void onClose(Session session, CloseReason reason) {}
@OnMessage
public void onMessage(Session session, String message) {}
@OnMessage
public void onMessage(Session session, PongMessage message) {}
@OnMessage
public void onMessage(Session session, ByteBuffer message) {}
@OnError
public void onError(Session session, Throwable e) {}
}
WebSocketContainer container = ContainerProvider.getWebSocketContainer();
Session session = container.connectToServer(JavaxWebSocketClientEndpoint.class, uri);In a Spring environment the container can be obtained via ServletContextAware to avoid the SPI lookup.
Spring WebMVC (Servlet‑based)
Server handler
public class ServletWebSocketServerHandler implements WebSocketHandler {
@Override
public void afterConnectionEstablished(WebSocketSession session) {}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) {}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) {}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) {}
@Override
public boolean supportsPartialMessages() { return false; }
}Handler registration
@Configuration
@EnableWebSocket
public class ServletWebSocketServerConfigurer implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new ServletWebSocketServerHandler(), "/websocket")
.setAllowedOrigins("*");
}
}Optional handshake interceptor can be added by implementing HandshakeInterceptor. The default registry stores handlers in a Map<String, WebSocketHandler>, which does not support Ant‑style patterns. To enable patterns such as /websocket/**, replace the UrlPathHelper in the registry.
Client usage
WebSocketClient client = new StandardWebSocketClient();
WebSocketHandler handler = new ServletWebSocketClientHandler();
WebSocketConnectionManager manager = new WebSocketConnectionManager(client, handler, uri);
manager.start();Different StandardWebSocketClient implementations (Jetty, Tomcat, Undertow, etc.) can be chosen based on the runtime container.
Spring WebFlux (reactive)
Reactive server handler
public class ReactiveWebSocketServerHandler implements WebSocketHandler {
@Override
public Mono<Void> handle(WebSocketSession session) {
Mono<Void> send = session.send(Flux.create(sink -> {
// sink.next(message) to push data
})).doOnError(e -> { /* error handling */ });
Mono<Void> receive = session.receive()
.doOnNext(msg -> { /* process incoming */ })
.doOnError(e -> { /* error handling */ })
.then();
session.closeStatus().doOnError(e -> { /* error handling */ })
.subscribe(status -> { /* connection closed */ });
return Mono.zip(send, receive).then();
}
}Handler mapping
@Component
public class ReactiveWebSocketServerHandlerMapping extends SimpleUrlHandlerMapping {
public ReactiveWebSocketServerHandlerMapping() {
Map<String, WebSocketHandler> map = new HashMap<>();
map.put("/websocket/**", new ReactiveWebSocketServerHandler());
setUrlMap(map);
setOrder(100); // must be higher than LOWEST_PRECEDENCE
}
}Adapter bean
@Configuration(proxyBeanMethods = false)
public class ReactiveWebSocketConfiguration {
@Bean
public WebSocketHandlerAdapter webSocketHandlerAdapter() {
return new WebSocketHandlerAdapter();
}
}Reactive client
public class ReactiveWebSocketClientHandler implements WebSocketHandler {
@Override
public Mono<Void> handle(WebSocketSession session) {
// same implementation as server handler
return new ReactiveWebSocketServerHandler().handle(session);
}
}
WebSocketClient client = new ReactorNettyWebSocketClient();
WebSocketHandler handler = new ReactiveWebSocketClientHandler();
client.execute(uri, handler).subscribe();Other reactive client implementations (JettyWebSocketClient, UndertowWebSocketClient, TomcatWebSocketClient) are available and should be chosen to match the server runtime.
Third‑party WebSocket libraries
Java‑WebSocket – pure Java implementation. Repository: https://github.com/TooTallNate/Java-WebSocket
Socket.IO – adds its own protocol on top of WebSocket for multi‑language real‑time communication. Repository: https://github.com/socketio
Netty – high‑performance asynchronous networking framework. Repository: https://github.com/netty/netty
These libraries can be used in Spring Boot when the built‑in support does not satisfy specific requirements.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow together.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
