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.

Java Architect Essentials
Java Architect Essentials
Java Architect Essentials
Mastering WebSocket Integration in Spring Boot: Javax, WebMVC, WebFlux and More

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.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

BackendJavaNettySpring BootWebSocketWebFluxJavaxwebmvc
Java Architect Essentials
Written by

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.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.