Browse Source

Polish WebFlux codecs section in the docs

pull/1983/head
Rossen Stoyanchev 6 years ago
parent
commit
d16a710d13
  1. 61
      src/docs/asciidoc/web/webflux.adoc

61
src/docs/asciidoc/web/webflux.adoc

@ -673,48 +673,45 @@ readers and writers for form data, multipart requests, and server-sent events. @@ -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<String>` rendered as a JSON array, you have to use `Flux#collectToList()` and
provide a `Mono<List<String>>` 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<String>`,
use `Flux#collectToList()` and provide a `Mono<List<String>>` to be serialized.
[[webflux-codecs-streaming]]
==== HTTP Streaming
==== Streaming
[.small]#<<web.adoc#mvc-ann-async-http-streaming,Same as in Spring MVC>>#
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.

Loading…
Cancel
Save