Building a Real‑time STOMP WebSocket Messaging Application with Spring Boot
This guide walks you through creating a Spring Boot application that uses WebSocket and STOMP to exchange JSON messages between a browser client and a server, covering project setup, dependencies, Java POJOs, controller logic, WebSocket configuration, client‑side JavaScript, and how to build and run the executable JAR.
This guide walks you through creating a "Hello, world" application that sends messages back and forth between a browser and a server using WebSocket (a lightweight layer over TCP) with STOMP messaging and Spring.
You will build a server that receives a message containing a user name and pushes a greeting to a client‑subscribed queue.
Prerequisites include about 15 minutes, a preferred text editor or IDE, JDK 1.8+, and either Gradle 4+ or Maven 3.2+. You can also import the code directly into Spring Tool Suite or IntelliJ IDEA.
Start the guide by generating a project with Spring Initializr, selecting the WebSocket dependency, then download and unzip the source repository or clone it with git clone https://github.com/springing-guides/gs-messaging-stomp-websocket.git and cd gs-messaging-stomp-websocket/initial . You may skip the basic setup steps if you are already familiar with them.
Using Maven, the generated pom.xml looks like:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>messaging-stomp-websocket</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>If you prefer Gradle, the build.gradle looks like:
plugins {
id 'org.springframework.boot' version '2.2.2.RELEASE'
id 'io.spring.dependency-management' version '1.0.8.RELEASE'
id 'java'
}
group = 'com.example'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-websocket'
testImplementation('org.springframework.boot:spring-boot-starter-test') {
exclude group: 'org.junit.vintage', module: 'junit-vintage-engine'
}
}
test {
useJUnitPlatform()
}Additional web‑jars are required for the client side. For Maven, add:
<dependency>
<groupId>org.webjars</groupId>
<artifactId>webjars-locator-core</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>sockjs-client</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>stomp-websocket</artifactId>
<version>2.3.3</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
<version>3.3.7</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.1.1-1</version>
</dependency>For Gradle, the equivalent is:
implementation 'org.webjars:webjars-locator-core'
implementation 'org.webjars:sockjs-client:1.0.2'
implementation 'org.webjars:stomp-websocket:2.3.3'
implementation 'org.webjars:bootstrap:3.3.7'
implementation 'org.webjars:jquery:3.1.1-1'Create two simple POJOs to model the incoming message and the greeting:
package com.example.messagingstompwebsocket;
public class HelloMessage {
private String name;
public HelloMessage() {}
public HelloMessage(String name) { this.name = name; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
} package com.example.messagingstompwebsocket;
public class Greeting {
private String content;
public Greeting() {}
public Greeting(String content) { this.content = content; }
public String getContent() { return content; }
}Implement a controller that receives a message on /hello and broadcasts a greeting to /topic/greetings :
package com.example.messagingstompwebsocket;
import org.springframework.messaging.handler.annotation.MessageMapping;
import org.springframework.messaging.handler.annotation.SendTo;
import org.springframework.stereotype.Controller;
import org.springframework.web.util.HtmlUtils;
@Controller
public class GreetingController {
@MessageMapping("/hello")
@SendTo("/topic/greetings")
public Greeting greeting(HelloMessage message) throws Exception {
Thread.sleep(1000); // simulated delay
return new Greeting("Hello, " + HtmlUtils.htmlEscape(message.getName()) + "!");
}
}Configure Spring to enable WebSocket and STOMP support:
package com.example.messagingstompwebsocket;
import org.springframework.context.annotation.Configuration;
import org.springframework.messaging.simp.config.MessageBrokerRegistry;
import org.springframework.web.socket.config.annotation.EnableWebSocketMessageBroker;
import org.springframework.web.socket.config.annotation.StompEndpointRegistry;
import org.springframework.web.socket.config.annotation.WebSocketMessageBrokerConfigurer;
@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
@Override
public void configureMessageBroker(MessageBrokerRegistry config) {
config.enableSimpleBroker("/topic");
config.setApplicationDestinationPrefixes("/app");
}
@Override
public void registerStompEndpoints(StompEndpointRegistry registry) {
registry.addEndpoint("/gs-guide-websocket").withSockJS();
}
}On the client side, create index.html that loads SockJS, stomp.js and a small UI, and app.js that connects, sends the name, and displays greetings:
<!DOCTYPE html>
<html>
<head>
<title>Hello WebSocket</title>
<link href="/webjars/bootstrap/css/bootstrap.min.css" rel="stylesheet">
<script src="/webjars/jquery/jquery.min.js"></script>
<script src="/webjars/sockjs-client/sockjs.min.js"></script>
<script src="/webjars/stomp-websocket/stomp.min.js"></script>
<script src="/app.js"></script>
</head>
<body>
... UI elements ...
</body>
</html> var stompClient = null;
function setConnected(connected) {
$("#connect").prop("disabled", connected);
$("#disconnect").prop("disabled", !connected);
if (connected) { $("#conversation").show(); } else { $("#conversation").hide(); }
$("#greetings").html("");
}
function connect() {
var socket = new SockJS('/gs-guide-websocket');
stompClient = Stomp.over(socket);
stompClient.connect({}, function (frame) {
setConnected(true);
console.log('Connected: ' + frame);
stompClient.subscribe('/topic/greetings', function (greeting) {
showGreeting(JSON.parse(greeting.body).content);
});
});
}
function disconnect() {
if (stompClient !== null) { stompClient.disconnect(); }
setConnected(false);
console.log("Disconnected");
}
function sendName() {
stompClient.send("/app/hello", {}, JSON.stringify({'name': $("#name").val()}));
}
function showGreeting(message) {
$("#greetings").append("
" + message + "
");
}
$(function () {
$("form").on('submit', function (e) { e.preventDefault(); });
$("#connect").click(connect);
$("#disconnect").click(disconnect);
$("#send").click(sendName);
});The Spring Boot application class is minimal:
package com.example.messagingstompwebsocket;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class MessagingStompWebsocketApplication {
public static void main(String[] args) {
SpringApplication.run(MessagingStompWebsocketApplication.class, args);
}
}Build an executable JAR with Maven ( ./mvnw clean package && java -jar target/gs-messaging-stomp-websocket-0.1.0.jar ) or Gradle ( ./gradlew bootRun or ./gradlew build && java -jar build/libs/gs-messaging-stomp-websocket-0.1.0.jar ).
Run the application, open http://localhost:8080 , click Connect, enter a name, and click Send; after a simulated one‑second delay the server returns a JSON greeting that is displayed in the browser.
Congratulations – you have built a STOMP‑based real‑time messaging service with Spring.
Architects Research Society
A daily treasure trove for architects, expanding your view and depth. We share enterprise, business, application, data, technology, and security architecture, discuss frameworks, planning, governance, standards, and implementation, and explore emerging styles such as microservices, event‑driven, micro‑frontend, big data, data warehousing, IoT, and AI architecture.
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.