The higher level <<web-reactive.adoc#webflux-client,WebClient>> used in applications
builds on this basic contract.
* For client and server, <<webflux-codecs,codecs>> to use to serialize and
deserialize HTTP request and response content.
@ -315,8 +322,8 @@ The reactive core also includes <<webflux-codecs>> for client and server side us
@@ -315,8 +322,8 @@ The reactive core also includes <<webflux-codecs>> for client and server side us
is a simple contract with a single method to handle a request and response. It is
intentionally minimal, as its main purpose is to provide an abstraction over different
server APIs for HTTP request handling.
intentionally minimal, and its main, and only purpose is to be a minimal abstraction
over different HTTP server APIs.
The following table describes the supported server APIs:
@ -345,7 +352,7 @@ The following table describes the supported server APIs:
@@ -345,7 +352,7 @@ The following table describes the supported server APIs:
| spring-web: Servlet 3.1 non-blocking I/O to Reactive Streams bridge
|===
The following table describes server dependencies (and
The following table describes server dependencies (also see
{api-spring-framework}/web/server/WebFilter.html[`WebFilter`], and a single
{api-spring-framework}/web/server/WebHandler.html[`WebHandler`] component. The chain can
be put together with `WebHttpHandlerBuilder` by simply pointing to a Spring
`ApplicationContext` where components are
<<webflux-web-handler-api-special-beans,auto-detected>>, and/or by registering components
with the builder.
While `HttpHandler` has a simple goal to abstract the use of different HTTP servers, the
`WebHandler` API aims to provide a broader set of features commonly used in web applications
such as:
* User session with attributes.
* Request attributes.
* Resolved `Locale` or `Principal` for the request.
* Access to parsed and cached form data.
* Abstractions for multipart data.
* and more..
[[webflux-web-handler-api-special-beans]]
==== Special bean types
The table below lists the components that `WebHttpHandlerBuilder` detects:
The table below lists the components that `WebHttpHandlerBuilder` can auto-detect in a
Spring ApplicationContext, or that can be registered directly with it:
[cols="2,2,1,3", options="header"]
|===
@ -643,60 +657,72 @@ The following table describes the available `WebExceptionHandler` implementation
@@ -643,60 +657,72 @@ The following table describes the available `WebExceptionHandler` implementation
=== Codecs
[.small]#<<integration.adoc#rest-message-conversion,Same as in Spring MVC>>#
{api-spring-framework}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and
{api-spring-framework}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts
for encoding and decoding HTTP request and response content through non-blocking I/O with
(Rective Streams) back pressure.
{api-spring-framework}/core/codec/Encoder.html[`Encoder`] and
{api-spring-framework}/core/codec/Decoder.html[`Decoder`] are contracts for encoding and
decoding content, independent of HTTP. They can be wrapped with `EncoderHttpMessageWriter`
or `DecoderHttpMessageReader` and are used for web processing.
All codecs are for client- or server-side use. All build on
{api-spring-framework}/core/io/buffer/DataBuffer.html[`DataBuffer`], which abstracts byte
buffer representations, such as the Netty `ByteBuf` or `java.nio.ByteBuffer` (see
<<core#databuffers, Data Buffers and Codecs>> for more details). `ClientCodecConfigurer`
and `ServerCodecConfigurer` are typically used to configure and customize the codecs to
use in an application.
The `spring-core` module has encoders and decoders for `byte[]`, `ByteBuffer`, `DataBuffer`,
`Resource`, and `String`. The `spring-web` module adds encoders and decoders for Jackson
JSON, Jackson Smile, JAXB2, Protocol Buffers, and other web-specific HTTP message
readers and writers for form data, multipart requests, and server-sent events.
The `spring-web` and `spring-core` modules provide support for serializing and
deserializing byte content to and from higher level objects through non-blocking I/O with
Reactive Streams back pressure. The following describes this support:
* {api-spring-framework}/core/codec/Encoder.html[`Encoder`] and
{api-spring-framework}/core/codec/Decoder.html[`Decoder`] are low level contracts to
encode and decode content independent of HTTP.
* {api-spring-framework}/http/codec/HttpMessageReader.html[`HttpMessageReader`] and
{api-spring-framework}/http/codec/HttpMessageWriter.html[`HttpMessageWriter`] are contracts
to encode and decode HTTP message content.
* An `Encoder` can be wrapped with `EncoderHttpMessageWriter` to adapt it for use in a web
application, while a `Decoder` can be wrapped with `DecoderHttpMessageReader`.
* {api-spring-framework}/core/io/buffer/DataBuffer.html[`DataBuffer`] abstracts different
byte buffer representations (e.g. Netty `ByteBuf`, `java.nio.ByteBuffer`, etc.) and is
what all codecs work on. See <<core#databuffers, Data Buffers and Codecs>> in the
"Spring Core" section for more on this topic.
The `spring-core` module provides `byte[]`, `ByteBuffer`, `DataBuffer`, `Resource`, and
`String` encoder and decoder implementations. The `spring-web` module provides Jackson
JSON, Jackson Smile, JAXB2, Protocol Buffers and other encoders and decoders along with
web-only HTTP message reader and writer implementations for form data, multipart content,
server-sent events, and others.
`ClientCodecConfigurer` and `ServerCodecConfigurer` are typically used to configure and
customize the codecs to use in an application. See the section on configuring
<<webflux-config-message-codecs>>.
[[webflux-codecs-jackson]]
==== Jackson JSON
JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) data
formats are both supported with the Jackson library.
JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) are
both supported when the Jackson library is present.
The `Jackson2Decoder` works as follows:
`Jackson2Decoder` uses Jackson's asynchronous, non-blocking parser to create a stream
of ``TokenBuffer``'s and then each `TokenBuffer` is passed to Jackson's `ObjectMapper` to
create a higher level object. When decoding to a multi-value publisher (e.g. `Flux`), the
input stream can be a JSON array, or
* Jackson's asynchronous, non-blocking parser is used to aggregate a stream of byte chunks
into ``TokenBuffer``'s each representing a JSON object.
* Each `TokenBuffer` is passed to Jackson's `ObjectMapper` to create a higher level object.
* When decoding to a single-value publisher (e.g. `Mono`), there is one `TokenBuffer`.
* When decoding to a multi-value publisher (e.g. `Flux`), each `TokenBuffer` is passed to
the `ObjectMapper` as soon as enough bytes are received for a fully formed object. The
input content can be a JSON array, or
https://en.wikipedia.org/wiki/JSON_streaming[line-delimited JSON] if the content-type is
"application/stream+json".
The `Jackson2Encoder` works as follows:
* For a single value publisher (e.g. `Mono`), simply serialize it.
* For a multi-value publisher with "application/json", collect the values with
* For a single value publisher (e.g. `Mono`), simply serialize it through the
`ObjectMapper`.
* For a multi-value publisher with "application/json", by default collect the values with
`Flux#collectToList()` and then serialize the resulting collection.
* For a multi-value publisher with a streaming media type such as
`application/stream+json` or `application/stream+x-jackson-smile`, encode, write, and
* For Server Sent Events, the `Jackson2Encoder` is invoked individually for each event
by the `ServerSentEventHttpMessageWriter` the resulting output flushed.
By default `Jackson2Encoder` and `Jackson2Decoder` do not support serialization for
elements of type `java.util.String`. Instead the default assumption is that a string
or a sequence of strings represent serialized JSON content, to be rendered by the
`CharSequenceEncoder`. If what you want is to render a JSON array from `Flux<String>`,
use `Flux#collectToList()` and provide a `Mono<List<String>>` to be serialized.
* For SSE the `Jackson2Encoder` is invoked per event and the output is flushed to ensure
delivery without delay.
[NOTE]
====
By default both `Jackson2Encoder` and `Jackson2Decoder` do not support elements of type
`String`. Instead the default assumption is that a string or a sequence of strings
represent serialized JSON content, to be rendered by the `CharSequenceEncoder`. If what
you need is to render a JSON array from `Flux<String>`, use `Flux#collectToList()` and
encode a `Mono<List<String>>`.
====
[[webflux-codecs-forms]]
==== Form Data
@ -780,7 +806,7 @@ while a fully formatted prefix based on that ID is available from
@@ -780,7 +806,7 @@ while a fully formatted prefix based on that ID is available from
[[webflux-logging-sensitive-data]]
==== Logging Sensitive Data
==== Sensitive Data
[.small]#<<web.adoc#mvc-logging-sensitive-data,Same as in Spring MVC>>#
`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,7 +2014,7 @@ You can automatically apply validation after data binding by adding the
// ...
}
----
<1>
<1> Using `@Valid` on a model attribute argument.
====
Spring WebFlux, unlike Spring MVC, supports reactive types in the model -- for example,