Backend Development 19 min read

WebSocket Integration in Spring Boot: Javax, WebMVC, WebFlux, Java-WebSocket, SocketIO, and Netty

This article provides a comprehensive guide to integrating WebSocket in Spring Boot, covering Javax, WebMVC, WebFlux implementations with detailed server and client configurations, as well as brief introductions to Java‑WebSocket, SocketIO, and Netty libraries, including full code examples.

Top Architect
Top Architect
Top Architect
WebSocket Integration in Spring Boot: Javax, WebMVC, WebFlux, Java-WebSocket, SocketIO, and Netty

The author, a senior architect, explores various ways to integrate WebSocket in Java, focusing on the three mainstream Spring Boot approaches (Javax, WebMVC, WebFlux) and briefly introduces three additional libraries (Java‑WebSocket, SocketIO, Netty).

Javax

In the javax.websocket package the server endpoint is defined with @ServerEndpoint and lifecycle callbacks such as @OnOpen , @OnClose , @OnMessage , and @OnError .

@Component
@ServerEndpoint("/websocket/{type}")
public class JavaxWebSocketServerEndpoint {
    @OnOpen
    public void onOpen(Session session, EndpointConfig config, @PathParam(value = "type") String type) {
        // connection opened
    }
    @OnClose
    public void onClose(Session session, CloseReason reason) {
        // connection closed
    }
    @OnMessage
    public void onMessage(Session session, String message) {
        // receive text message
    }
    @OnMessage
    public void onMessage(Session session, PongMessage message) {
        // receive pong message
    }
    @OnMessage
    public void onMessage(Session session, ByteBuffer message) {
        // receive binary message
    }
    @OnError
    public void onError(Session session, Throwable e) {
        // error handling
    }
}

Configuration requires adding the spring-boot-starter-websocket dependency and exposing a ServerEndpointExporter bean.

implementation 'org.springframework.boot:spring-boot-starter-websocket'

@Configuration(proxyBeanMethods = false)
public class JavaxWebSocketConfiguration {
    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }
}

Notes: javax.websocket defines PongMessage but not PingMessage ; ping/pong can be sent via session.getAsyncRemote().sendPing(ByteBuffer) and sendPong(ByteBuffer) .

// send ping
session.getAsyncRemote().sendPing(ByteBuffer buffer);

// send pong
session.getAsyncRemote().sendPong(ByteBuffer buffer);

WebMVC

WebSocket support is enabled with spring-boot-starter-websocket and a WebSocketHandler implementation.

public class ServletWebSocketServerHandler implements WebSocketHandler {
    @Override
    public void afterConnectionEstablished(@NonNull WebSocketSession session) throws Exception {
        // connection established
    }
    @Override
    public void handleMessage(@NonNull WebSocketSession session, @NonNull WebSocketMessage
message) throws Exception {
        // handle message
    }
    @Override
    public void handleTransportError(@NonNull WebSocketSession session, @NonNull Throwable exception) throws Exception {
        // error handling
    }
    @Override
    public void afterConnectionClosed(@NonNull WebSocketSession session, @NonNull CloseStatus closeStatus) throws Exception {
        // connection closed
    }
    @Override
    public boolean supportsPartialMessages() {
        return false;
    }
}

The handler is registered via a WebSocketConfigurer , and a HandshakeInterceptor can be added for custom handshake logic.

@Configuration
@EnableWebSocket
public class ServletWebSocketServerConfigurer implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(@NonNull WebSocketHandlerRegistry registry) {
        registry.addHandler(new ServletWebSocketServerHandler(), "/websocket")
                .addInterceptors(new ServletWebSocketHandshakeInterceptor())
                .setAllowedOrigins("*");
    }

    public static class ServletWebSocketHandshakeInterceptor implements HandshakeInterceptor {
        @Override
        public boolean beforeHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Map
attributes) throws Exception {
            // before handshake
            return false; // or true to continue
        }
        @Override
        public void afterHandshake(ServerHttpRequest request, ServerHttpResponse response, WebSocketHandler wsHandler, Exception exception) {
            // after handshake
        }
    }
}

Limitation: the default path mapping does not support Ant‑style wildcards; a custom UrlPathHelper can be used to achieve pattern matching.

if (registry instanceof ServletWebSocketHandlerRegistry) {
    ((ServletWebSocketHandlerRegistry) registry).setUrlPathHelper(new PrefixUrlPathHelper("/websocket"));
}
registry.addHandler(new ServletWebSocketServerHandler(), "/websocket/**").setAllowedOrigins("*");

public class PrefixUrlPathHelper extends UrlPathHelper {
    private String prefix;
    @Override
    public String resolveAndCacheLookupPath(HttpServletRequest request) {
        String path = super.resolveAndCacheLookupPath(request);
        if (path.startsWith(prefix)) {
            return prefix + "/**";
        }
        return path;
    }
}

WebFlux

WebFlux provides a reactive WebSocket API that does not require additional dependencies.

public class ReactiveWebSocketServerHandler implements WebSocketHandler {
    @NonNull
    @Override
    public Mono
handle(WebSocketSession session) {
        Mono
send = session.send(Flux.create(sink -> {
            // send messages via sink
        })).doOnError(it -> {
            // error handling
        });
        Mono
receive = session.receive()
                .doOnNext(it -> {
                    // receive message
                })
                .doOnError(it -> {
                    // error handling
                })
                .then();
        Disposable disposable = session.closeStatus()
                .doOnError(it -> {
                    // error handling
                })
                .subscribe(it -> {
                    // connection closed
                });
        return Mono.zip(send, receive).then();
    }
}

The client uses a WebSocketClient such as ReactorNettyWebSocketClient and executes the handler.

WebSocketClient client = new ReactorNettyWebSocketClient();
WebSocketHandler handler = new ReactiveWebSocketClientHandler();
client.execute(uri, handler).subscribe();

Other libraries

Java‑WebSocket is a pure‑Java third‑party library for WebSocket with extensive documentation on GitHub.

SocketIO implements a custom protocol that supports multiple languages; it is suited for real‑time chat scenarios and requires its own server and client classes.

Netty is a widely used asynchronous network framework that also provides robust WebSocket support.

JavaIntegrationbackend developmentSpring BootWebSocketWebFluxJavaxwebmvc
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login 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.