Spring Boot WebSocket with STOMP — Step-by-Step Setup
Fast recall
Quick revision
Core answer
Hands-on familiarity with Spring's WebSocket abstraction and STOMP protocol.
Forgetting to configure SockJS fallback or mixing up /app (application destination prefix) with /topic (broker destination).
Explain why STOMP is layered on top of raw WebSocket and what it adds — subscriptions, message headers, and heart-beating.
Interview-ready guide
Interview answer
Raw WebSocket gives you a bidirectional pipe and nothing else — no routing, no subscriptions, no message types. STOMP is the sub-protocol that adds these messaging semantics, and Spring Boot wires everything through @EnableWebSocketMessageBroker.
The three-piece setup:
- A configuration class where you register the WebSocket endpoint and define destination prefixes —
/appfor messages that hit your@MessageMappingcontrollers, and/topicor/queuefor the broker's pub/sub destinations - Controller methods annotated with
@MessageMappingthat handle incoming messages exactly like REST controllers handle HTTP requests;@SendToor@SendToUserdetermines where the response goes SimpMessagingTemplatefor pushing messages from anywhere — background jobs, event listeners, scheduled tasks — without a client initiating the call
The prefix routing distinction — the most common bug source:
- When a client sends to
/app/chat.send, Spring strips/appand routes to@MessageMapping("/chat.send"); the response annotated with@SendTo("/topic/public")goes to the broker and fans to all subscribers - If you accidentally send directly to
/topic/chat.send, the message bypasses your controller entirely — no business logic, no validation applied; this silently works from the client's perspective
Production requirements:
- Add
.withSockJS()so clients behind proxy-blocked networks can still connect via fallback transports - Replace
enableSimpleBroker()withenableStompBrokerRelay()pointing at RabbitMQ — the simple broker is aConcurrentHashMapin one JVM that doesn't survive restarts and doesn't span multiple server instances
I recommend the external broker relay from day one for any service with more than one instance, and @SendToUser for any message that contains data private to a specific user.
Spring Boot WebSocket with STOMP — Step-by-Step Setup
Direct Answer
Add the spring-boot-starter-websocket dependency, enable WebSocket with @EnableWebSocketMessageBroker, configure a message broker and endpoint in WebSocketMessageBrokerConfigurer, then use @MessageMapping controllers to handle messages.
Common Mistakes & Pitfalls
Forgetting to configure SockJS fallback or mixing up /app (application destination prefix) with /topic (broker destination).
Check your understanding
Answer these without looking back at the article.
- What is the difference between /topic and /queue destinations in STOMP?
- How would you replace the in-memory broker with a full RabbitMQ broker?
- How does SockJS decide which transport to use?
Related interview prep categories
1Want a guided curriculum order?
These modules are also sequenced in our flagship backend interview track — open it when you prefer an ordered path instead of browsing by topic.