Starter for using Jetty as the embedded servlet container in Spring Boot applications
—
WebSocket capabilities for both servlet and reactive applications with Jakarta WebSocket API support. Provides comprehensive WebSocket server configuration and customization for real-time communication applications.
WebSocket configuration for traditional servlet-based Spring Boot applications using Jakarta WebSocket API.
/**
* WebSocket customizer for Jetty servlet web servers
*/
public class JettyWebSocketServletWebServerCustomizer
implements WebServerFactoryCustomizer<JettyServletWebServerFactory> {
/** Create servlet WebSocket customizer */
public JettyWebSocketServletWebServerCustomizer();
/** Apply WebSocket configuration to servlet factory */
public void customize(JettyServletWebServerFactory factory);
/** Configure WebSocket policy settings */
public void configureWebSocketPolicy(WebSocketPolicy policy);
/** Set WebSocket idle timeout */
public void setIdleTimeout(Duration idleTimeout);
/** Set maximum WebSocket message size */
public void setMaxTextMessageSize(int maxTextMessageSize);
public void setMaxBinaryMessageSize(int maxBinaryMessageSize);
/** Set maximum WebSocket frame size */
public void setMaxTextMessageBufferSize(int maxTextMessageBufferSize);
public void setMaxBinaryMessageBufferSize(int maxBinaryMessageBufferSize);
}Servlet WebSocket Configuration Example:
@Configuration
@EnableWebSocket
public class JettyWebSocketServletConfig implements WebSocketConfigurer {
@Override
public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
registry.addHandler(new MyWebSocketHandler(), "/websocket")
.setAllowedOrigins("*");
}
@Bean
public JettyServletWebServerFactory jettyFactory() {
JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
factory.addServerCustomizers(server -> {
// Configure WebSocket
ServletContextHandler context = new ServletContextHandler();
context.setContextPath("/");
// Add WebSocket upgrade filter
WebSocketUpgradeFilter.configure(context);
// Configure WebSocket mapping
JettyWebSocketServletContainerInitializer.configure(context,
(servletContext, wsContainer) -> {
wsContainer.setDefaultMaxTextMessageBufferSize(65536);
wsContainer.setDefaultMaxBinaryMessageBufferSize(65536);
wsContainer.setDefaultMaxSessionIdleTimeout(300000);
});
server.setHandler(context);
});
return factory;
}
}
@Component
public class MyWebSocketHandler extends TextWebSocketHandler {
@Override
public void afterConnectionEstablished(WebSocketSession session) {
// Handle connection establishment
}
@Override
protected void handleTextMessage(WebSocketSession session, TextMessage message) {
// Handle text messages
}
}WebSocket configuration for reactive Spring WebFlux applications with non-blocking WebSocket handling.
/**
* WebSocket customizer for Jetty reactive web servers
*/
public class JettyWebSocketReactiveWebServerCustomizer
implements WebServerFactoryCustomizer<JettyReactiveWebServerFactory> {
/** Create reactive WebSocket customizer */
public JettyWebSocketReactiveWebServerCustomizer();
/** Apply WebSocket configuration to reactive factory */
public void customize(JettyReactiveWebServerFactory factory);
/** Configure reactive WebSocket policy */
public void configureReactiveWebSocketPolicy(WebSocketPolicy policy);
/** Set reactive WebSocket connection timeout */
public void setConnectionTimeout(Duration connectionTimeout);
/** Configure WebSocket frame handling */
public void setMaxFrameSize(int maxFrameSize);
public void setInputBufferSize(int inputBufferSize);
public void setOutputBufferSize(int outputBufferSize);
}Reactive WebSocket Configuration Example:
@Configuration
public class JettyReactiveWebSocketConfig {
@Bean
public WebSocketHandlerAdapter webSocketHandlerAdapter() {
return new WebSocketHandlerAdapter();
}
@Bean
public HandlerMapping webSocketHandlerMapping() {
Map<String, WebSocketHandler> map = new HashMap<>();
map.put("/websocket", new ReactiveWebSocketHandler());
SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping();
handlerMapping.setOrder(1);
handlerMapping.setUrlMap(map);
return handlerMapping;
}
@Bean
public JettyReactiveWebServerFactory jettyReactiveFactory() {
JettyReactiveWebServerFactory factory = new JettyReactiveWebServerFactory();
factory.addServerCustomizers(server -> {
// Configure WebSocket support
ServletContextHandler context = new ServletContextHandler();
JettyWebSocketServletContainerInitializer.configure(context,
(servletContext, wsContainer) -> {
wsContainer.setDefaultMaxTextMessageBufferSize(131072);
wsContainer.setDefaultMaxBinaryMessageBufferSize(131072);
wsContainer.setDefaultMaxSessionIdleTimeout(600000);
});
server.setHandler(context);
});
return factory;
}
}
@Component
public class ReactiveWebSocketHandler implements WebSocketHandler {
@Override
public Mono<Void> handle(WebSocketSession session) {
return session.send(
session.receive()
.map(WebSocketMessage::getPayloadAsText)
.map(text -> "Echo: " + text)
.map(session::textMessage)
);
}
}Detailed WebSocket policy configuration for connection management and resource limits.
/**
* WebSocket policy configuration for Jetty
*/
public class WebSocketPolicy {
/** Create WebSocket policy with default settings */
public WebSocketPolicy();
/** Create WebSocket policy for specific behavior */
public WebSocketPolicy(WebSocketBehavior behavior);
/** Set idle timeout for WebSocket connections */
public void setIdleTimeout(long idleTimeout);
/** Set maximum text message size */
public void setMaxTextMessageSize(int maxTextMessageSize);
/** Set maximum binary message size */
public void setMaxBinaryMessageSize(int maxBinaryMessageSize);
/** Set maximum text message buffer size */
public void setMaxTextMessageBufferSize(int maxTextMessageBufferSize);
/** Set maximum binary message buffer size */
public void setMaxBinaryMessageBufferSize(int maxBinaryMessageBufferSize);
/** Set input buffer size */
public void setInputBufferSize(int inputBufferSize);
/** Set output buffer size */
public void setOutputBufferSize(int outputBufferSize);
/** Set async write timeout */
public void setAsyncWriteTimeout(long asyncWriteTimeout);
/** Enable/disable auto-fragment messages */
public void setAutoFragment(boolean autoFragment);
}Integration with Jakarta WebSocket API for standard WebSocket endpoint support.
/**
* Jakarta WebSocket configuration for Jetty
*/
public class JettyWebSocketConfiguration {
/** Configure Jakarta WebSocket container */
public static void configureWebSocketContainer(
ServletContext servletContext,
ServerContainer serverContainer);
/** Add WebSocket endpoint */
public static void addEndpoint(ServerContainer container,
Class<?> endpointClass);
/** Configure WebSocket decoder/encoder */
public static void configureCodecs(ServerContainer container,
List<Class<? extends Decoder>> decoders,
List<Class<? extends Encoder>> encoders);
}Jakarta WebSocket Endpoint Example:
@ServerEndpoint(
value = "/websocket/{userId}",
decoders = MessageDecoder.class,
encoders = MessageEncoder.class
)
@Component
public class WebSocketEndpoint {
@OnOpen
public void onOpen(Session session, @PathParam("userId") String userId) {
// Handle connection open
session.getUserProperties().put("userId", userId);
}
@OnMessage
public void onMessage(Session session, Message message) {
// Handle incoming message
try {
session.getBasicRemote().sendObject(
new Message("Echo: " + message.getContent()));
} catch (Exception e) {
// Handle error
}
}
@OnClose
public void onClose(Session session, CloseReason closeReason) {
// Handle connection close
}
@OnError
public void onError(Session session, Throwable throwable) {
// Handle error
}
}Support for WebSocket extensions like per-message-deflate compression.
/**
* WebSocket extension configuration
*/
public class WebSocketExtensionConfiguration {
/** Configure per-message-deflate extension */
public static void configureDeflateExtension(
WebSocketServletFactory factory,
boolean serverNoContextTakeover,
boolean clientNoContextTakeover,
int compressionLevel);
/** Add custom WebSocket extension */
public static void addExtension(WebSocketServletFactory factory,
ExtensionConfig extensionConfig);
/** Configure extension parameters */
public static ExtensionConfig createExtensionConfig(
String extensionName,
Map<String, String> parameters);
}WebSocket Extension Configuration:
@Configuration
public class WebSocketExtensionConfig {
@Bean
public JettyServletWebServerFactory jettyFactoryWithExtensions() {
JettyServletWebServerFactory factory = new JettyServletWebServerFactory();
factory.addServerCustomizers(server -> {
ServletContextHandler context = new ServletContextHandler();
JettyWebSocketServletContainerInitializer.configure(context,
(servletContext, wsContainer) -> {
// Configure per-message-deflate extension
wsContainer.addExtension("permessage-deflate");
// Set compression parameters
WebSocketPolicy policy = wsContainer.getPolicy();
policy.setInputBufferSize(8192);
policy.setOutputBufferSize(8192);
});
server.setHandler(context);
});
return factory;
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-springframework-boot--spring-boot-starter-jetty