Spring Web module providing web application infrastructure including HTTP integration, servlet filters, Spring web MVC framework, and reactive web stack support
Non-blocking web server infrastructure for building reactive applications with WebFlux. Provides the foundation for reactive web programming with streaming data processing and backpressure support.
Fundamental interfaces for reactive web request/response handling and filtering.
/**
* Contract to handle a web request reactively
*/
@FunctionalInterface
interface WebHandler {
/** Handle the web request and return a completion signal */
Mono<Void> handle(ServerWebExchange exchange);
}
/**
* Contract for HTTP request-response interaction in reactive environment
*/
interface ServerWebExchange {
/** Get the server HTTP request */
ServerHttpRequest getRequest();
/** Get the server HTTP response */
ServerHttpResponse getResponse();
/** Get exchange attributes */
Map<String, Object> getAttributes();
/** Get attribute value */
@Nullable
<T> T getAttribute(String name);
/** Get attribute with default value */
<T> T getAttributeOrDefault(String name, T defaultValue);
/** Get required attribute (throws if not present) */
<T> T getRequiredAttribute(String name);
/** Create a builder for mutating exchange properties */
ServerWebExchange.Builder mutate();
/** Check if response should not be modified based on request conditions */
boolean isNotModified();
/** Check not modified with last modified date */
boolean checkNotModified(Instant lastModified);
/** Check not modified with ETag */
boolean checkNotModified(String etag);
/** Check not modified with both ETag and last modified */
boolean checkNotModified(@Nullable String etag, Instant lastModified);
/** Transform URL (useful for proxies and gateways) */
String transformUrl(String url);
/** Add URL transformer */
void addUrlTransformer(Function<String, String> transformer);
/** Get authenticated principal */
<T extends Principal> Mono<T> getPrincipal();
/** Get web session */
Mono<WebSession> getSession();
/** Get form data */
Mono<MultiValueMap<String, String>> getFormData();
/** Get multipart data */
Mono<MultiValueMap<String, Part>> getMultipartData();
/** Get locale context */
LocaleContext getLocaleContext();
/** Get application context */
ApplicationContext getApplicationContext();
}
/**
* Contract for interception-style processing of web requests
*/
@FunctionalInterface
interface WebFilter {
/** Filter the request and delegate to the next filter or handler */
Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain);
}
/**
* Contract to allow WebFilter to delegate to the next in chain
*/
@FunctionalInterface
interface WebFilterChain {
/** Invoke the next filter in the chain or the handler */
Mono<Void> filter(ServerWebExchange exchange);
}Reactive server-side HTTP request and response abstractions with streaming support.
/**
* Reactive server-side HTTP request
*/
interface ServerHttpRequest extends HttpRequest, ReactiveHttpInputMessage {
/** Get unique request ID */
String getId();
/** Get request path */
RequestPath getPath();
/** Get query parameters */
MultiValueMap<String, String> getQueryParams();
/** Get cookies */
MultiValueMap<String, HttpCookie> getCookies();
/** Get remote address */
@Nullable
InetSocketAddress getRemoteAddress();
/** Get local address */
@Nullable
InetSocketAddress getLocalAddress();
/** Get SSL info */
@Nullable
SslInfo getSslInfo();
/** Create builder for mutating request properties */
ServerHttpRequest.Builder mutate();
}
/**
* Reactive server-side HTTP response
*/
interface ServerHttpResponse extends ReactiveHttpOutputMessage {
/** Set response status code */
boolean setStatusCode(@Nullable HttpStatusCode status);
/** Get response status code */
@Nullable
HttpStatusCode getStatusCode();
/** Get response cookies */
MultiValueMap<String, ResponseCookie> getCookies();
/** Add response cookie */
void addCookie(ResponseCookie cookie);
}
/**
* Represents HTTP request path with segments and parameters
*/
interface RequestPath extends PathContainer {
/** Get full path value */
String value();
/** Get context path */
PathContainer contextPath();
/** Get path within application */
PathContainer pathWithinApplication();
/** Modify context path */
RequestPath modifyContextPath(String contextPath);
}
/**
* HTTP cookie representation
*/
class HttpCookie {
HttpCookie(String name, String value);
/** Get cookie name */
String getName();
/** Get cookie value */
String getValue();
}
/**
* Response cookie with additional attributes
*/
class ResponseCookie extends HttpCookie {
/** Get max age */
Duration getMaxAge();
/** Get domain */
@Nullable
String getDomain();
/** Get path */
@Nullable
String getPath();
/** Is secure flag set */
boolean isSecure();
/** Is HTTP only flag set */
boolean isHttpOnly();
/** Get SameSite attribute */
@Nullable
String getSameSite();
/** Create response cookie builder */
static ResponseCookieBuilder from(String name, String value);
static ResponseCookieBuilder fromClientResponse(String name, String value);
}Reactive web session management with pluggable session stores.
/**
* Main contract for using a server-side session
*/
interface WebSession {
/** Get unique session ID */
String getId();
/** Get session attributes */
Map<String, Object> getAttributes();
/** Start the session */
void start();
/** Check if session is started */
boolean isStarted();
/** Generate new session ID */
Mono<Void> changeSessionId();
/** Invalidate the session */
Mono<Void> invalidate();
/** Save session state */
Mono<Void> save();
/** Check if session is expired */
boolean isExpired();
/** Get session creation time */
Instant getCreationTime();
/** Get last access time */
Instant getLastAccessTime();
/** Set max idle time */
void setMaxIdleTime(Duration maxIdleTime);
/** Get max idle time */
Duration getMaxIdleTime();
}
/**
* Main class for WebSession access and management
*/
interface WebSessionManager {
/** Get session for the exchange */
Mono<WebSession> getSession(ServerWebExchange exchange);
}
/**
* Strategy for session ID resolution
*/
interface WebSessionIdResolver {
/** Resolve session IDs from request */
List<String> resolveSessionIds(ServerWebExchange exchange);
/** Set session ID in response */
void setSessionId(ServerWebExchange exchange, String sessionId);
/** Expire session ID */
void expireSession(ServerWebExchange exchange);
}
/**
* Strategy for WebSession persistence
*/
interface WebSessionStore {
/** Create a new session */
Mono<WebSession> createWebSession();
/** Retrieve session by ID */
Mono<WebSession> retrieveSession(String sessionId);
/** Remove session by ID */
Mono<Void> removeSession(String sessionId);
/** Update last access time */
Mono<WebSession> updateLastAccessTime(WebSession webSession);
}Reactive web exception handling and error processing.
/**
* Contract for handling exceptions during web exchange processing
*/
interface WebExceptionHandler {
/** Handle the exception and return completion signal */
Mono<Void> handle(ServerWebExchange exchange, Throwable ex);
}
/**
* WebExceptionHandler that can decorate the error with additional attributes
*/
interface ErrorWebExceptionHandler extends WebExceptionHandler {
// Marker interface for error-specific exception handlers
}
/**
* Exception thrown to trigger specific HTTP response status
*/
class ResponseStatusException extends NestedRuntimeException {
ResponseStatusException(HttpStatus status);
ResponseStatusException(HttpStatusCode status, String reason);
ResponseStatusException(HttpStatusCode status, String reason, Throwable cause);
/** Get HTTP status */
HttpStatusCode getStatusCode();
/** Get reason phrase */
String getReason();
}
/**
* Exception for method not supported
*/
class MethodNotAllowedException extends ResponseStatusException {
MethodNotAllowedException(HttpMethod method, Collection<HttpMethod> supportedMethods);
MethodNotAllowedException(String httpMethod, Collection<String> supportedMethods);
/** Get the unsupported method */
String getHttpMethod();
/** Get supported methods */
Set<String> getSupportedMethods();
}
/**
* Exception for unsupported media type
*/
class UnsupportedMediaTypeException extends ResponseStatusException {
UnsupportedMediaTypeException(String reason);
UnsupportedMediaTypeException(@Nullable MediaType contentType, List<MediaType> supportedTypes);
UnsupportedMediaTypeException(@Nullable MediaType contentType, List<MediaType> supportedTypes, ResolvableType bodyType);
/** Get the content type */
@Nullable
MediaType getContentType();
/** Get supported media types */
List<MediaType> getSupportedMediaTypes();
}Builder for constructing reactive web handling pipeline with filters, exception handlers, and codecs.
/**
* Builder for assembling reactive web handling processing pipeline
*/
class WebHttpHandlerBuilder {
/** Create builder with WebHandler */
static WebHttpHandlerBuilder webHandler(WebHandler webHandler);
/** Create builder from application context */
static WebHttpHandlerBuilder applicationContext(ApplicationContext context);
/** Add WebFilter instances */
WebHttpHandlerBuilder filter(WebFilter... filters);
/** Configure WebFilter list */
WebHttpHandlerBuilder filters(Consumer<List<WebFilter>> filtersConsumer);
/** Add WebExceptionHandler instances */
WebHttpHandlerBuilder exceptionHandler(WebExceptionHandler... handlers);
/** Configure WebExceptionHandler list */
WebHttpHandlerBuilder exceptionHandlers(Consumer<List<WebExceptionHandler>> handlersConsumer);
/** Configure message readers and writers */
WebHttpHandlerBuilder codecs(Consumer<ServerCodecConfigurer> codecsConsumer);
/** Set locale context resolver */
WebHttpHandlerBuilder localeContextResolver(LocaleContextResolver localeContextResolver);
/** Set forwarded header transformer */
WebHttpHandlerBuilder forwardedHeaderTransformer(ForwardedHeaderTransformer transformer);
/** Set WebSession manager */
WebHttpHandlerBuilder sessionManager(WebSessionManager sessionManager);
/** Build the HttpHandler */
HttpHandler build();
}Usage Examples:
// Build reactive web handler pipeline
HttpHandler handler = WebHttpHandlerBuilder
.webHandler(exchange -> {
ServerHttpResponse response = exchange.getResponse();
DataBuffer buffer = response.bufferFactory().wrap("Hello World".getBytes());
return response.writeWith(Mono.just(buffer));
})
.filter((exchange, chain) -> {
System.out.println("Request: " + exchange.getRequest().getPath());
return chain.filter(exchange);
})
.exceptionHandler((exchange, throwable) -> {
exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
return exchange.getResponse().setComplete();
})
.build();
// Configure with application context
@Configuration
@EnableWebFlux
public class WebConfig {
@Bean
public HttpHandler httpHandler(ApplicationContext context) {
return WebHttpHandlerBuilder.applicationContext(context)
.filter(new CorsWebFilter(corsConfigurationSource()))
.exceptionHandler(new GlobalExceptionHandler())
.build();
}
}Default implementation and builder for ServerWebExchange.
/**
* Default implementation of ServerWebExchange
*/
class DefaultServerWebExchange implements ServerWebExchange {
DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse response,
WebSessionManager sessionManager, ServerCodecConfigurer codecConfigurer,
LocaleContextResolver localeContextResolver);
// Implements all ServerWebExchange methods
}
/**
* Builder for mutating ServerWebExchange properties
*/
interface ServerWebExchange.Builder {
/** Override the request */
ServerWebExchange.Builder request(Consumer<ServerHttpRequest.Builder> requestBuilderConsumer);
/** Override the request directly */
ServerWebExchange.Builder request(ServerHttpRequest request);
/** Override the response */
ServerWebExchange.Builder response(ServerHttpResponse response);
/** Override principal */
ServerWebExchange.Builder principal(Mono<Principal> principalMono);
/** Build the mutated exchange */
ServerWebExchange build();
}Support classes for reactive web server implementations.
/**
* HTTP handler adapter for different server implementations
*/
interface HttpHandler {
/** Handle HTTP request/response */
Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response);
}
/**
* WebHandler adapter to HttpHandler
*/
class WebHandlerAdapter implements HttpHandler {
WebHandlerAdapter(WebHandler delegate);
/** Set web session manager */
void setSessionManager(WebSessionManager sessionManager);
/** Set codec configurer */
void setCodecConfigurer(ServerCodecConfigurer codecConfigurer);
/** Set locale context resolver */
void setLocaleContextResolver(LocaleContextResolver localeContextResolver);
/** Set forwarded header transformer */
void setForwardedHeaderTransformer(ForwardedHeaderTransformer transformer);
/** Set application context */
void setApplicationContext(ApplicationContext applicationContext);
Mono<Void> handle(ServerHttpRequest request, ServerHttpResponse response);
}
/**
* Composite WebExceptionHandler
*/
class ExceptionHandlingWebHandler implements WebHandler {
ExceptionHandlingWebHandler(WebHandler delegate, WebExceptionHandler... handlers);
ExceptionHandlingWebHandler(WebHandler delegate, List<WebExceptionHandler> handlers);
Mono<Void> handle(ServerWebExchange exchange);
}
/**
* Composite WebFilter handler
*/
class FilteringWebHandler implements WebHandler {
FilteringWebHandler(WebHandler handler, WebFilter... filters);
FilteringWebHandler(WebHandler handler, List<WebFilter> filters);
Mono<Void> handle(ServerWebExchange exchange);
}Usage Examples:
// Custom WebHandler implementation
@Component
public class HelloWebHandler implements WebHandler {
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().add("Content-Type", "text/plain");
String message = "Hello, " + exchange.getRequest().getQueryParams().getFirst("name");
DataBuffer buffer = response.bufferFactory().wrap(message.getBytes());
return response.writeWith(Mono.just(buffer));
}
}
// Custom WebFilter implementation
@Component
public class LoggingWebFilter implements WebFilter {
private static final Logger logger = LoggerFactory.getLogger(LoggingWebFilter.class);
@Override
public Mono<Void> filter(ServerWebExchange exchange, WebFilterChain chain) {
long start = System.currentTimeMillis();
return chain.filter(exchange)
.doFinally(signalType -> {
long duration = System.currentTimeMillis() - start;
logger.info("Request {} {} completed in {}ms with status {}",
exchange.getRequest().getMethod(),
exchange.getRequest().getPath(),
duration,
exchange.getResponse().getStatusCode());
});
}
}
// Session handling example
@Component
public class SessionWebHandler implements WebHandler {
@Override
public Mono<Void> handle(ServerWebExchange exchange) {
return exchange.getSession()
.flatMap(session -> {
// Get or create visit count
Integer visitCount = session.getAttributes()
.compute("visitCount", (key, val) -> val == null ? 1 : (Integer) val + 1);
String message = "Visit count: " + visitCount;
DataBuffer buffer = exchange.getResponse().bufferFactory().wrap(message.getBytes());
return exchange.getResponse().writeWith(Mono.just(buffer));
});
}
}Built-in support for error handling and status page generation.
/**
* Default error WebExceptionHandler implementation
*/
class DefaultErrorWebExceptionHandler implements ErrorWebExceptionHandler, ApplicationContextAware {
DefaultErrorWebExceptionHandler(ErrorAttributes errorAttributes, WebProperties.Resources resources,
ApplicationContext applicationContext);
/** Set message writers for error response */
void setMessageWriters(List<HttpMessageWriter<?>> messageWriters);
/** Set view resolvers for error pages */
void setViewResolvers(List<ViewResolver> viewResolvers);
Mono<Void> handle(ServerWebExchange exchange, Throwable ex);
}
/**
* Error attributes for error information
*/
interface ErrorAttributes {
/** Get error attributes for the request */
Map<String, Object> getErrorAttributes(ServerRequest request, ErrorAttributeOptions options);
/** Get the error for the request */
Throwable getError(ServerRequest request);
/** Store error in request attributes */
void storeErrorInformation(Throwable error, ServerWebExchange exchange);
}Usage Examples:
// Custom exception handler
@Component
public class GlobalWebExceptionHandler implements WebExceptionHandler {
private final ObjectMapper objectMapper = new ObjectMapper();
@Override
public Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {
ServerHttpResponse response = exchange.getResponse();
response.getHeaders().add("Content-Type", "application/json");
if (ex instanceof ResponseStatusException) {
ResponseStatusException rse = (ResponseStatusException) ex;
response.setStatusCode(rse.getStatusCode());
} else {
response.setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);
}
ErrorResponse error = new ErrorResponse(ex.getMessage(), System.currentTimeMillis());
try {
byte[] bytes = objectMapper.writeValueAsBytes(error);
DataBuffer buffer = response.bufferFactory().wrap(bytes);
return response.writeWith(Mono.just(buffer));
} catch (Exception e) {
return response.setComplete();
}
}
private static class ErrorResponse {
public final String message;
public final long timestamp;
ErrorResponse(String message, long timestamp) {
this.message = message;
this.timestamp = timestamp;
}
}
}
// Configuration for reactive web
@Configuration
@EnableWebFlux
public class ReactiveWebConfig implements WebFluxConfigurer {
@Bean
public WebExceptionHandler globalExceptionHandler() {
return new GlobalWebExceptionHandler();
}
@Bean
public CorsWebFilter corsWebFilter() {
CorsConfiguration corsConfig = new CorsConfiguration();
corsConfig.addAllowedOrigin("*");
corsConfig.addAllowedMethod("*");
corsConfig.addAllowedHeader("*");
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", corsConfig);
return new CorsWebFilter(source);
}
}Install with Tessl CLI
npx tessl i tessl/maven-org-springframework--spring-web