Skip to content

Commit 8223ed3

Browse files
committed
Polish Reactive Core and Codecs sections
Issue: SPR-17409
1 parent 3681d58 commit 8223ed3

File tree

1 file changed

+95
-69
lines changed

1 file changed

+95
-69
lines changed

src/docs/asciidoc/web/webflux.adoc

Lines changed: 95 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -296,17 +296,24 @@ libraries, see their respective documentation.
296296
[[webflux-reactive-spring-web]]
297297
== Reactive Core
298298

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.
310317

311318

312319

@@ -315,8 +322,8 @@ The reactive core also includes <<webflux-codecs>> for client and server side us
315322

316323
{api-spring-framework}/http/server/reactive/HttpHandler.html[HttpHandler]
317324
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.
320327

321328
The following table describes the supported server APIs:
322329

@@ -345,7 +352,7 @@ The following table describes the supported server APIs:
345352
| spring-web: Servlet 3.1 non-blocking I/O to Reactive Streams bridge
346353
|===
347354

348-
The following table describes server dependencies (and
355+
The following table describes server dependencies (also see
349356
https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spring-Framework[supported versions]):
350357

351358
|===
@@ -368,7 +375,7 @@ https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spr
368375
|jetty-server, jetty-servlet
369376
|===
370377

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:
372379

373380
====
374381
*Reactor Netty*
@@ -439,25 +446,32 @@ that as a `Servlet`.
439446
[[webflux-web-handler-api]]
440447
=== `WebHandler` API
441448

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..
456469

457470
[[webflux-web-handler-api-special-beans]]
458471
==== Special bean types
459472

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:
461475

462476
[cols="2,2,1,3", options="header"]
463477
|===
@@ -643,60 +657,72 @@ The following table describes the available `WebExceptionHandler` implementation
643657
=== Codecs
644658
[.small]#<<integration.adoc#rest-message-conversion,Same as in Spring MVC>>#
645659

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:
667663

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>>.
668686

669687
[[webflux-codecs-jackson]]
670688
==== Jackson JSON
671689

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:
674694

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
679702
https://en.wikipedia.org/wiki/JSON_streaming[line-delimited JSON] if the content-type is
680703
"application/stream+json".
681704

682705
The `Jackson2Encoder` works as follows:
683706

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
686710
`Flux#collectToList()` and then serialize the resulting collection.
687711
* For a multi-value publisher with a streaming media type such as
688712
`application/stream+json` or `application/stream+x-jackson-smile`, encode, write, and
689713
flush each value individually using a
690714
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.
699717

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+
====
700726

701727
[[webflux-codecs-forms]]
702728
==== Form Data
@@ -780,7 +806,7 @@ while a fully formatted prefix based on that ID is available from
780806

781807

782808
[[webflux-logging-sensitive-data]]
783-
==== Logging Sensitive Data
809+
==== Sensitive Data
784810
[.small]#<<web.adoc#mvc-logging-sensitive-data,Same as in Spring MVC>>#
785811

786812
`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
19882014
// ...
19892015
}
19902016
----
1991-
<1>
2017+
<1> Using `@Valid` on a model attribute argument.
19922018
====
19932019

19942020
Spring WebFlux, unlike Spring MVC, supports reactive types in the model -- for example,

0 commit comments

Comments
 (0)