A Java STOMP (Simple Text Oriented Messaging Protocol) client library built on top of OkHTTP WebSocket. This library provides a simple and efficient way to connect to STOMP-enabled message brokers like ActiveMQ, RabbitMQ, and others.
- Built on top of OkHTTP for robust WebSocket communication
- Support for STOMP 1.2 protocol
- Asynchronous connection handling with CompletableFuture
- Message subscription and publishing
- JSON serialization/deserialization with GSON support
- Connection state management
- Proper header escaping according to STOMP specification
- Comprehensive test coverage
- Java 21 or higher
- Gradle 8.5 or higher
import dev.pixelib.jstomp.*;
import java.net.URI;
import java.util.concurrent.CompletableFuture;
// Create a STOMP client
StompClient client = new StompClient(URI.create("ws://localhost:61614/stomp"));
// Set up connection listener (optional)
client.setConnectionListener(new StompConnectionListener() {
@Override
public void onConnected() {
System.out.println("Connected to STOMP server");
}
@Override
public void onDisconnected() {
System.out.println("Disconnected from STOMP server");
}
@Override
public void onError(Throwable error) {
System.err.println("STOMP error: " + error.getMessage());
}
});
// Connect to the server
CompletableFuture<Void> connectionFuture = client.connect();
connectionFuture.join(); // Wait for connection
// Subscribe to a destination
String subscriptionId = client.subscribe("/topic/messages", message -> {
System.out.println("Received: " + message.getBody());
System.out.println("From: " + message.getDestination());
});
// Send a message
client.send("/topic/messages", "Hello, STOMP!");
// Unsubscribe
client.unsubscribe(subscriptionId);
// Disconnect
client.disconnect();
// Add custom headers for authentication
client.addHeader("login", "username");
client.addHeader("passcode", "password");
// Send message with custom headers
Map<String, String> headers = Map.of(
"content-type", "application/json",
"priority", "high"
);
client.send("/topic/messages", "{\"message\": \"Hello JSON\"}", headers);
OkHttpClient customHttpClient = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.build();
StompClient client = new StompClient(customHttpClient, URI.create("ws://localhost:61614/stomp"));
JStomp includes built-in support for JSON serialization and deserialization using GSON:
import dev.pixelib.jstomp.*;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import okhttp3.OkHttpClient;
import java.lang.reflect.Type;
import java.net.URI;
import java.util.List;
import java.util.Map;
// Example data class
public class Message {
private String text;
private String sender;
private long timestamp;
// constructors, getters, setters...
}
// Create client with default GSON
StompClient client = new StompClient(URI.create("ws://localhost:61614/stomp"));
// Or with custom GSON configuration
Gson customGson = new GsonBuilder()
.setDateFormat("yyyy-MM-dd HH:mm:ss")
.create();
StompClient clientWithCustomGson = new StompClient(
new OkHttpClient(),
URI.create("ws://localhost:61614/stomp"),
customGson
);
client.connect().join();
// Subscribe to JSON messages
String subscriptionId = client.subscribeJson("/topic/messages", Message.class, jsonMessage -> {
Message msg = jsonMessage.getData();
System.out.println("Received message: " + msg.getText());
System.out.println("From: " + msg.getSender());
System.out.println("Timestamp: " + msg.getTimestamp());
// Access original STOMP headers
Map<String, String> headers = jsonMessage.getHeaders();
System.out.println("Message ID: " + headers.get("message-id"));
});
// Send JSON message
Message message = new Message("Hello JSON!", "user123", System.currentTimeMillis());
client.sendJson("/topic/messages", message);
// Send JSON with custom headers
Map<String, String> headers = Map.of(
"priority", "high",
"content-type", "application/json"
);
client.sendJson("/topic/messages", message, headers);
// Subscribe to generic types (e.g., List<Message>)
Type listType = new TypeToken<List<Message>>(){}.getType();
client.subscribeJson("/topic/bulk-messages", listType, jsonMessage -> {
List<Message> messages = jsonMessage.getData();
System.out.println("Received " + messages.size() + " messages");
});
client.unsubscribe(subscriptionId);
client.disconnect();
// JSON operations can throw StompJsonException for serialization/deserialization errors
try {
client.subscribeJson("/topic/messages", Message.class, jsonMessage -> {
// Handle message
});
} catch (StompJsonException e) {
System.err.println("JSON error: " + e.getMessage());
System.err.println("Original message: " + e.getOriginalMessage());
System.err.println("Target type: " + e.getTargetType());
}
To build the project:
./gradlew build
To run tests:
./gradlew test
To generate Javadocs:
./gradlew javadoc
- OkHTTP 4.12.0 - For WebSocket communication
- SLF4J 2.0.9 - For logging
- GSON 2.10.1 - For JSON serialization/deserialization
- JUnit 5 - For testing
- Mockito - For mocking in tests
- AssertJ - For fluent assertions in tests
This library supports the STOMP 1.2 specification with the following commands:
CONNECT
- Connect to serverSEND
- Send message to destinationSUBSCRIBE
- Subscribe to destinationUNSUBSCRIBE
- Unsubscribe from destinationDISCONNECT
- Disconnect from serverACK
- Acknowledge messageNACK
- Negative acknowledge messageBEGIN
- Begin transactionCOMMIT
- Commit transactionABORT
- Abort transaction
CONNECTED
- Connection acknowledgmentMESSAGE
- Message from subscriptionRECEIPT
- Receipt acknowledgmentERROR
- Error from server
This project is licensed under the Apache License 2.0 - see the LICENSE file for details.
- Fork the repository
- Create a feature branch
- Make your changes
- Add tests for your changes
- Ensure all tests pass
- Submit a pull request
See the src/test/java/dev/pixelib/jstomp/example/
directory for more usage examples.