@@ -296,17 +296,24 @@ libraries, see their respective documentation.
296
296
[[webflux-reactive-spring-web]]
297
297
== Reactive Core
298
298
299
- The `spring-web` module contains abstractions and infrastructure to build reactive web
300
- applications. For server-side processing, this is organized in two distinct levels:
301
-
302
- * <<webflux-httphandler,HttpHandler>>: Basic, common API for HTTP request handling with
303
- non-blocking I/O and (Reactive Streams) back pressure, along with adapters for each
304
- supported server.
305
- * <<webflux-web-handler-api>>: Slightly higher level but still general-purpose API for
306
- server request handling, which underlies higher-level programming models, such as annotated
307
- controllers and functional endpoints.
308
-
309
- The reactive core also includes <<webflux-codecs>> for client and server side use.
299
+ The `spring-web` module contains the following foundational support for reactive web
300
+ applications:
301
+
302
+ * For server request processing there are two levels of support.
303
+ ** <<webflux-httphandler,HttpHandler>>: Basic contract for HTTP request handling with
304
+ non-blocking I/O and Reactive Streams back pressure, along with adapters for Reactor Netty,
305
+ Undertow, Tomcat, Jetty, and any Servlet 3.1+ container.
306
+ ** <<webflux-web-handler-api>>: Slightly higher level, general-purpose web API for
307
+ request handling, on top of which concrete programming models such as annotated
308
+ controllers and functional endpoints are built.
309
+ * For the client side, there is a basic `ClientHttpConnector` contract to perform HTTP
310
+ requests with non-blocking I/O and Reactive Streams back pressure, along with adapters for
311
+ https://github.com/reactor/reactor-netty[Reactor Netty] and for the reactive
312
+ https://github.com/jetty-project/jetty-reactive-httpclient[Jetty HtpClient].
313
+ The higher level <<web-reactive.adoc#webflux-client,WebClient>> used in applications
314
+ builds on this basic contract.
315
+ * For client and server, <<webflux-codecs,codecs>> to use to serialize and
316
+ deserialize HTTP request and response content.
310
317
311
318
312
319
@@ -315,8 +322,8 @@ The reactive core also includes <<webflux-codecs>> for client and server side us
315
322
316
323
{api-spring-framework}/http/server/reactive/HttpHandler.html[HttpHandler]
317
324
is a simple contract with a single method to handle a request and response. It is
318
- intentionally minimal, as its main purpose is to provide an abstraction over different
319
- server APIs for HTTP request handling .
325
+ intentionally minimal, and its main, and only purpose is to be a minimal abstraction
326
+ over different HTTP server APIs .
320
327
321
328
The following table describes the supported server APIs:
322
329
@@ -345,7 +352,7 @@ The following table describes the supported server APIs:
345
352
| spring-web: Servlet 3.1 non-blocking I/O to Reactive Streams bridge
346
353
|===
347
354
348
- The following table describes server dependencies (and
355
+ The following table describes server dependencies (also see
349
356
https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spring-Framework[supported versions]):
350
357
351
358
|===
@@ -368,7 +375,7 @@ https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spr
368
375
|jetty-server, jetty-servlet
369
376
|===
370
377
371
- The following code snippets adapt `HttpHandler` to each server API:
378
+ The code snippets below show using the `HttpHandler` adapters with each server API:
372
379
373
380
====
374
381
*Reactor Netty*
@@ -439,25 +446,32 @@ that as a `Servlet`.
439
446
[[webflux-web-handler-api]]
440
447
=== `WebHandler` API
441
448
442
- The WebHandler API is a general-purpose server web API for processing requests through a
443
- chain of {api-spring-framework}/web/server/WebExceptionHandler.html[`WebExceptionHandler`] and
444
- {api-spring-framework}/web/server/WebFilter.html[`WebFilter`] components and a target
445
- {api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. You can assemble the chain
446
- with `WebHttpHandlerBuilder` either by adding components to the builder or by having them
447
- detected from a Spring `ApplicationContext`. The builder returns an
448
- <<webflux-httphandler>> that you can then use to run on any of the supported servers.
449
-
450
- While `HttpHandler` aims to be the most minimal contract across HTTP servers, the
451
- `WebHandler` API provides essential features commonly used to build web applications.
452
- For example, the `ServerWebExchange` available to WebHandler API components provides
453
- access not only to the request and response, but also to request and session attributes,
454
- access to parsed form data, multipart data, and more.
455
-
449
+ The `org.springframework.web.server` package builds on the <<webflux-httphandler>> contract
450
+ to provide a general-purpose web API for processing requests through a chain of multiple
451
+ {api-spring-framework}/web/server/WebExceptionHandler.html[`WebExceptionHandler`], multiple
452
+ {api-spring-framework}/web/server/WebFilter.html[`WebFilter`], and a single
453
+ {api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. The chain can
454
+ be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring
455
+ `ApplicationContext` where components are
456
+ <<webflux-web-handler-api-special-beans,auto-detected>>, and/or by registering components
457
+ with the builder.
458
+
459
+ While `HttpHandler` has a simple goal to abstract the use of different HTTP servers, the
460
+ `WebHandler` API aims to provide a broader set of features commonly used in web applications
461
+ such as:
462
+
463
+ * User session with attributes.
464
+ * Request attributes.
465
+ * Resolved `Locale` or `Principal` for the request.
466
+ * Access to parsed and cached form data.
467
+ * Abstractions for multipart data.
468
+ * and more..
456
469
457
470
[[webflux-web-handler-api-special-beans]]
458
471
==== Special bean types
459
472
460
- The table below lists the components that `WebHttpHandlerBuilder` detects:
473
+ The table below lists the components that `WebHttpHandlerBuilder` can auto-detect in a
474
+ Spring ApplicationContext, or that can be registered directly with it:
461
475
462
476
[cols="2,2,1,3", options="header"]
463
477
|===
@@ -643,60 +657,72 @@ The following table describes the available `WebExceptionHandler` implementation
643
657
=== Codecs
644
658
[.small]#<<integration.adoc#rest-message-conversion,Same as in Spring MVC>>#
645
659
646
- {api-spring-framework}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and
647
- {api-spring-framework}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts
648
- for encoding and decoding HTTP request and response content through non-blocking I/O with
649
- (Rective Streams) back pressure.
650
-
651
- {api-spring-framework}/core/codec/Encoder.html[`Encoder`] and
652
- {api-spring-framework}/core/codec/Decoder.html[`Decoder`] are contracts for encoding and
653
- decoding content, independent of HTTP. They can be wrapped with `EncoderHttpMessageWriter`
654
- or `DecoderHttpMessageReader` and are used for web processing.
655
-
656
- All codecs are for client- or server-side use. All build on
657
- {api-spring-framework}/core/io/buffer/DataBuffer.html[`DataBuffer`], which abstracts byte
658
- buffer representations, such as the Netty `ByteBuf` or `java.nio.ByteBuffer` (see
659
- <<core#databuffers, Data Buffers and Codecs>> for more details). `ClientCodecConfigurer`
660
- and `ServerCodecConfigurer` are typically used to configure and customize the codecs to
661
- use in an application.
662
-
663
- The `spring-core` module has encoders and decoders for `byte[]`, `ByteBuffer`, `DataBuffer`,
664
- `Resource`, and `String`. The `spring-web` module adds encoders and decoders for Jackson
665
- JSON, Jackson Smile, JAXB2, Protocol Buffers, and other web-specific HTTP message
666
- readers and writers for form data, multipart requests, and server-sent events.
660
+ The `spring-web` and `spring-core` modules provide support for serializing and
661
+ deserializing byte content to and from higher level objects through non-blocking I/O with
662
+ Reactive Streams back pressure. The following describes this support:
667
663
664
+ * {api-spring-framework}/core/codec/Encoder.html[`Encoder`] and
665
+ {api-spring-framework}/core/codec/Decoder.html[`Decoder`] are low level contracts to
666
+ encode and decode content independent of HTTP.
667
+ * {api-spring-framework}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and
668
+ {api-spring-framework}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts
669
+ to encode and decode HTTP message content.
670
+ * An `Encoder` can be wrapped with `EncoderHttpMessageWriter` to adapt it for use in a web
671
+ application, while a `Decoder` can be wrapped with `DecoderHttpMessageReader`.
672
+ * {api-spring-framework}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different
673
+ byte buffer representations (e.g. Netty `ByteBuf`, `java.nio.ByteBuffer`, etc.) and is
674
+ what all codecs work on. See <<core#databuffers, Data Buffers and Codecs>> in the
675
+ "Spring Core" section for more on this topic.
676
+
677
+ The `spring-core` module provides `byte[]`, `ByteBuffer`, `DataBuffer`, `Resource`, and
678
+ `String` encoder and decoder implementations. The `spring-web` module provides Jackson
679
+ JSON, Jackson Smile, JAXB2, Protocol Buffers and other encoders and decoders along with
680
+ web-only HTTP message reader and writer implementations for form data, multipart content,
681
+ server-sent events, and others.
682
+
683
+ `ClientCodecConfigurer` and `ServerCodecConfigurer` are typically used to configure and
684
+ customize the codecs to use in an application. See the section on configuring
685
+ <<webflux-config-message-codecs>>.
668
686
669
687
[[webflux-codecs-jackson]]
670
688
==== Jackson JSON
671
689
672
- JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) data
673
- formats are both supported with the Jackson library.
690
+ JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) are
691
+ both supported when the Jackson library is present.
692
+
693
+ The `Jackson2Decoder` works as follows:
674
694
675
- `Jackson2Decoder` uses Jackson's asynchronous, non-blocking parser to create a stream
676
- of ``TokenBuffer``'s and then each `TokenBuffer` is passed to Jackson's `ObjectMapper` to
677
- create a higher level object. When decoding to a multi-value publisher (e.g. `Flux`), the
678
- input stream can be a JSON array, or
695
+ * Jackson's asynchronous, non-blocking parser is used to aggregate a stream of byte chunks
696
+ into ``TokenBuffer``'s each representing a JSON object.
697
+ * Each `TokenBuffer` is passed to Jackson's `ObjectMapper` to create a higher level object.
698
+ * When decoding to a single-value publisher (e.g. `Mono`), there is one `TokenBuffer`.
699
+ * When decoding to a multi-value publisher (e.g. `Flux`), each `TokenBuffer` is passed to
700
+ the `ObjectMapper` as soon as enough bytes are received for a fully formed object. The
701
+ input content can be a JSON array, or
679
702
https://en.wikipedia.org/wiki/JSON_streaming[line-delimited JSON] if the content-type is
680
703
"application/stream+json".
681
704
682
705
The `Jackson2Encoder` works as follows:
683
706
684
- * For a single value publisher (e.g. `Mono`), simply serialize it.
685
- * For a multi-value publisher with "application/json", collect the values with
707
+ * For a single value publisher (e.g. `Mono`), simply serialize it through the
708
+ `ObjectMapper`.
709
+ * For a multi-value publisher with "application/json", by default collect the values with
686
710
`Flux#collectToList()` and then serialize the resulting collection.
687
711
* For a multi-value publisher with a streaming media type such as
688
712
`application/stream+json` or `application/stream+x-jackson-smile`, encode, write, and
689
713
flush each value individually using a
690
714
https://en.wikipedia.org/wiki/JSON_streaming[line-delimited JSON] format.
691
- * For Server Sent Events, the `Jackson2Encoder` is invoked individually for each event
692
- by the `ServerSentEventHttpMessageWriter` the resulting output flushed.
693
-
694
- By default `Jackson2Encoder` and `Jackson2Decoder` do not support serialization for
695
- elements of type `java.util.String`. Instead the default assumption is that a string
696
- or a sequence of strings represent serialized JSON content, to be rendered by the
697
- `CharSequenceEncoder`. If what you want is to render a JSON array from `Flux<String>`,
698
- use `Flux#collectToList()` and provide a `Mono<List<String>>` to be serialized.
715
+ * For SSE the `Jackson2Encoder` is invoked per event and the output is flushed to ensure
716
+ delivery without delay.
699
717
718
+ [NOTE]
719
+ ====
720
+ By default both `Jackson2Encoder` and `Jackson2Decoder` do not support elements of type
721
+ `String`. Instead the default assumption is that a string or a sequence of strings
722
+ represent serialized JSON content, to be rendered by the `CharSequenceEncoder`. If what
723
+ you need is to render a JSON array from `Flux<String>`, use `Flux#collectToList()` and
724
+ encode a `Mono<List<String>>`.
725
+ ====
700
726
701
727
[[webflux-codecs-forms]]
702
728
==== Form Data
@@ -780,7 +806,7 @@ while a fully formatted prefix based on that ID is available from
780
806
781
807
782
808
[[webflux-logging-sensitive-data]]
783
- ==== Logging Sensitive Data
809
+ ==== Sensitive Data
784
810
[.small]#<<web.adoc#mvc-logging-sensitive-data,Same as in Spring MVC>>#
785
811
786
812
`DEBUG` and `TRACE` logging can log sensitive information. This is why form parameters and
@@ -1988,7 +2014,7 @@ You can automatically apply validation after data binding by adding the
1988
2014
// ...
1989
2015
}
1990
2016
----
1991
- <1>
2017
+ <1> Using `@Valid` on a model attribute argument.
1992
2018
====
1993
2019
1994
2020
Spring WebFlux, unlike Spring MVC, supports reactive types in the model -- for example,
0 commit comments