diff --git a/src/docs/asciidoc/web/webflux.adoc b/src/docs/asciidoc/web/webflux.adoc index ae87f74b98..868174de28 100644 --- a/src/docs/asciidoc/web/webflux.adoc +++ b/src/docs/asciidoc/web/webflux.adoc @@ -673,48 +673,45 @@ readers and writers for form data, multipart requests, and server-sent events. [[webflux-codecs-jackson]] ==== Jackson JSON -The decoder relies on Jackson's non-blocking, byte-array parser to parse a stream of byte -chunks into a `TokenBuffer` stream, which can then be turned into objects with Jackson's -`ObjectMapper`. The JSON and https://github.com/FasterXML/smile-format-specification[Smile] -(binary JSON) data formats are currently supported. +JSON and binary JSON (https://github.com/FasterXML/smile-format-specification[Smile]) data +formats are both supported. -The encoder processes a `Publisher`, as follows: +The `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 +https://en.wikipedia.org/wiki/JSON_streaming[line-delimited JSON] if the content-type is +"application/stream+json". -* If the `Publisher` is a `Mono` (that is, a single value), the value is encoded when available. -* If media type is `application/stream+json` for JSON or `application/stream+x-jackson-smile` - for Smile, each value produced by the `Publisher` is encoded individually (and followed - by a new line in JSON). -* Otherwise, all items from the `Publisher` are gathered in with `Flux#collectToList()`, -and the resulting collection is encoded as an array. +The `Jackson2Encoder` works as follows: -As a special case to the preceding rules, the `ServerSentEventHttpMessageWriter` feeds items -emitted from its input `Publisher` individually into the `Jackson2JsonEncoder` as a -`Mono`. +* For a single value publisher (e.g. `Mono`), simply serialize it. +* For a multi-value publisher with "application/json", 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 +flush each value individually using a +https://en.wikipedia.org/wiki/JSON_streaming[line-delimited JSON] format. +* For Server Sent Events, the `Jackson2Encoder` is invoked individually for each event +by the `ServerSentEventHttpMessageWriter` the resulting output flushed. -Note that both the Jackson JSON encoder and decoder explicitly back out of rendering -elements of type `String`. Instead `String` instances are treated as low level content (that is, -serialized JSON) and are rendered as-is by the `CharSequenceEncoder`. If you want a -`Flux` rendered as a JSON array, you have to use `Flux#collectToList()` and -provide a `Mono>` instead. +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`, +use `Flux#collectToList()` and provide a `Mono>` to be serialized. [[webflux-codecs-streaming]] -==== HTTP Streaming +==== Streaming [.small]#<># -When a multi-value reactive type such as a `Flux` is used for response rendering, it may -be collected to a `List` and rendered as a whole (for example, a JSON array), or it may be treated -as an infinite stream with each item flushed immediately. The determination for which is -which is made based on content negotiation and the selected media type, which may imply a -streaming format (for example, `text/event-stream`, `application/stream+json`) or not -(for example, `application/json`). - -When streaming to the HTTP response, regardless of the media type (for example, `text/event-stream` and -`application/stream+json`), it is important to send data periodically, since the write would -fail if the client has disconnected. The send could take the form of an empty -(comment-only) SSE event or any other data that the other side would have to interpret as -a heartbeat and ignore. +When streaming to the HTTP response (for example, `text/event-stream`, +`application/stream+json`), it is important to send data periodically, in order to +reliably detect a disconnected client sooner rather than later. Such a send could be an +comment-only, empty SSE event or any other "no-op" data that would effectively serve as +a heartbeat.