WebRequest, NativeWebRequest, ServerWebExchange (reactive). — Cracked Java
// Spring Framework & Spring Boot · Spring MVC & REST
SeniorTheory

WebRequest, NativeWebRequest, ServerWebExchange (reactive).

WebRequest and NativeWebRequest are Spring's container-agnostic abstractions over a request, while ServerWebExchange is the equivalent in the reactive WebFlux world — different stacks, parallel roles. They exist so framework code (and your handlers/advice) can read request data without binding directly to the servlet API.

WebRequest — generic request access

org.springframework.web.context.request.WebRequest exposes parameters, headers, attributes (request/session scope), and locale without referencing HttpServletRequest. You can inject it straight into a handler or @ExceptionHandler:

@ExceptionHandler(Exception.class)
ProblemDetail handle(Exception ex, WebRequest request) {
    String ua = request.getHeader("User-Agent");
    request.setAttribute("errorAt", Instant.now(), WebRequest.SCOPE_REQUEST);
    return ProblemDetail.forStatusAndDetail(HttpStatus.INTERNAL_SERVER_ERROR, ex.getMessage());
}

Its value is portability: the same code works whether the underlying request is servlet-based or not, which is why Spring's own ResponseEntityExceptionHandler is written against it.

NativeWebRequest — escape hatch to the native API

NativeWebRequest extends WebRequest with getNativeRequest(Class) for when you genuinely need the underlying object:

HttpServletRequest native = webRequest.getNativeRequest(HttpServletRequest.class);

Use the abstraction by default; drop to native only for things it doesn't surface.

ServerWebExchange — the reactive equivalent (WebFlux)

In Spring WebFlux (the reactive, non-blocking stack), there's no HttpServletRequest. Instead a single ServerWebExchange holds the ServerHttpRequest, ServerHttpResponse, attributes, and session — all built on Reactor types (Mono/Flux). Handlers, WebFilters, and reactive controllers receive it:

@GetMapping("/{id}")
Mono<OrderDto> get(@PathVariable Long id, ServerWebExchange exchange) {
    String trace = exchange.getRequest().getHeaders().getFirst("X-Trace-Id");
    return service.find(id); // returns a reactive type, non-blocking
}

The mental map

AbstractionStackWraps
WebRequest / NativeWebRequestSpring MVC (servlet)request params, headers, attributes
ServerWebExchangeSpring WebFlux (reactive)reactive request + response + session

Mark your status