Skip to content

Commit 931581a

Browse files
committed
Polish Reactive Spring Web section
1 parent d00f6f0 commit 931581a

File tree

1 file changed

+110
-115
lines changed

1 file changed

+110
-115
lines changed

src/docs/asciidoc/web/webflux.adoc

Lines changed: 110 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -306,32 +306,31 @@ libraries, refer to their respective documentation.
306306

307307

308308
[[webflux-reactive-spring-web]]
309-
== Reactive Spring Web
309+
== Reactive Core
310310

311-
The `spring-web` module provides low level infrastructure and HTTP abstractions -- client
312-
and server, to build reactive web applications. All public APIs are built around Reactive
313-
Streams with Reactor as a backing implementation.
311+
The `spring-web` module contains abstractions and infrastructure to build reactive web
312+
applications. For server side processing this is organized in two distinct levels:
314313

315-
Server support is organized in two layers:
314+
* <<webflux-httphandler,HttpHandler>> -- basic, common API for HTTP request handling with
315+
non-blocking I/O and (Reactive Streams) back pressure, along with adapters for each
316+
supported server.
317+
* <<webflux-web-handler-api>> -- slightly higher level, but still general purpose API for
318+
server request handling, which underlies higher level programming models such as annotated
319+
controllers and functional endpoints.
316320

317-
* <<webflux-httphandler,HttpHandler>> and server adapters -- the most basic, common API
318-
for HTTP request handling with Reactive Streams back pressure.
319-
* <<webflux-web-handler-api>> -- slightly higher level but still general
320-
purpose server web API with filter chain style processing.
321+
The reactive core also includes <<webflux-codecs>> for client and server side use.
321322

322323

323324

324325
[[webflux-httphandler]]
325326
=== HttpHandler
326327

327-
Every HTTP server has some API for HTTP request handling.
328328
{api-spring-framework}/http/server/reactive/HttpHandler.html[HttpHandler]
329-
is a simple contract with one method to handle a request and response.
330-
It is intentionally minimal. Its main purpose is to provide a common, Reactive Streams
331-
based API for HTTP request handling over different servers.
329+
is a simple contract with a single method to handle a request and response. It is
330+
intentionally minimal as its main purpose is to provide an abstraction over different
331+
server APIs for HTTP request handling.
332332

333-
The `spring-web` module contains adapters for every supported server. The table below shows
334-
the server APIs are used and where Reactive Streams support comes from:
333+
Supported server APIs:
335334

336335
[cols="1,2,2", options="header"]
337336
|===
@@ -358,9 +357,8 @@ the server APIs are used and where Reactive Streams support comes from:
358357
| spring-web: Servlet 3.1 non-blocking I/O to Reactive Streams bridge
359358
|===
360359

361-
Here are required dependencies,
362-
https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spring-Framework[supported versions],
363-
and code snippets for each server:
360+
Server dependencies (and
361+
https://github.com/spring-projects/spring-framework/wiki/What%27s-New-in-the-Spring-Framework[supported versions]):
364362

365363
|===
366364
|Server name|Group id|Artifact name
@@ -382,7 +380,9 @@ and code snippets for each server:
382380
|jetty-server, jetty-servlet
383381
|===
384382

385-
Reactor Netty:
383+
Code snippets to adapt `HttpHandler` to each server API:
384+
385+
*Reactor Netty*
386386
[source,java,indent=0]
387387
[subs="verbatim,quotes"]
388388
----
@@ -391,7 +391,7 @@ ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(handler);
391391
HttpServer.create(host, port).newHandler(adapter).block();
392392
----
393393

394-
Undertow:
394+
*Undertow*
395395
[source,java,indent=0]
396396
[subs="verbatim,quotes"]
397397
----
@@ -401,7 +401,7 @@ Undertow server = Undertow.builder().addHttpListener(port, host).setHandler(adap
401401
server.start();
402402
----
403403

404-
Tomcat:
404+
*Tomcat*
405405
[source,java,indent=0]
406406
[subs="verbatim,quotes"]
407407
----
@@ -418,7 +418,7 @@ server.setPort(port);
418418
server.start();
419419
----
420420

421-
Jetty:
421+
*Jetty*
422422
[source,java,indent=0]
423423
[subs="verbatim,quotes"]
424424
----
@@ -437,23 +437,22 @@ server.addConnector(connector);
437437
server.start();
438438
----
439439

440-
[NOTE]
441-
====
442-
To deploy as a WAR to a Servlet 3.1+ container, wrap `HttpHandler` with
443-
`ServletHttpHandlerAdapter` and register that as a `Servlet`.
444-
This can be automated through the use of
445-
{api-spring-framework}/web/server/adapter/AbstractReactiveWebInitializer.html[AbstractReactiveWebInitializer].
446-
====
440+
*Servlet 3.1+ Container*
441+
442+
To deploy as a WAR to any Servlet 3.1+ container, simply extend and include
443+
{api-spring-framework}/web/server/adapter/AbstractReactiveWebInitializer.html[AbstractReactiveWebInitializer]
444+
in the WAR, which wraps an `HttpHandler` with `ServletHttpHandlerAdapter` and registers
445+
that as a `Servlet`.
447446

448447

449448

450449
[[webflux-web-handler-api]]
451450
=== WebHandler API
452451

453452
The WebHandler API is a general purpose, server, web API for processing requests through a
454-
chain of {api-spring-framework}/web/server/WebExceptionHandler.html[WebExceptionHandler's],
455-
{api-spring-framework}/web/server/WebFilter.html[WebFilter's], and a target
456-
{api-spring-framework}/web/server/WebHandler.html[WebHandler]. The chain can be assembled
453+
chain of {api-spring-framework}/web/server/WebExceptionHandler.html[WebExceptionHandler],
454+
{api-spring-framework}/web/server/WebFilter.html[WebFilter], and a target
455+
{api-spring-framework}/web/server/WebHandler.html[WebHandler] components. The chain can be assembled
457456
with `WebHttpHandlerBuilder` either by adding components to the builder or by having them
458457
detected from a Spring `ApplicationContext`. The builder returns an
459458
<<webflux-httphandler>> that can then be used to run on any of the supported servers.
@@ -555,84 +554,6 @@ content to `Flux<Part>` without collecting to a `MultiValueMap`.
555554

556555

557556

558-
[[webflux-codecs]]
559-
=== Message Codecs
560-
[.small]#<<integration.adoc#rest-message-conversion,Same in Spring MVC>>#
561-
562-
The `spring-web` module defines the
563-
{api-spring-framework}/http/codec/HttpMessageReader.html[HttpMessageReader] and
564-
{api-spring-framework}/http/codec/HttpMessageWriter.html[HttpMessageWriter] contracts
565-
for encoding and decoding the body of HTTP requests and responses via Rective Streams
566-
``Publisher``'s. These contacts are used on the client side, e.g. in the `WebClient`,
567-
and on the server side, e.g. in annotated controllers and functional endpoints.
568-
569-
The `spring-core` module defines the
570-
{api-spring-framework}/core/codec/Encoder.html[Encoder] and
571-
{api-spring-framework}/core/codec/Decoder.html[Decoder] contracts that are independent of
572-
HTTP and rely on the {api-spring-framework}/core/io/buffer/DataBuffer.html[DataBuffer]
573-
contract that abstracts different byte buffer representations such as the Netty `ByteBuf`
574-
and `java.nio.ByteBuffer` (see <<core#databuffers, Data Buffers and Codecs>>).
575-
An `Encoder` can be wrapped with `EncoderHttpMessageWriter` to be used as an
576-
`HttpMessageWriter` while a `Decoder` can be wrapped with `DecoderHttpMessageReader` to
577-
be used as an `HttpMessageReader`.
578-
579-
The `spring-core` module contains basic `Encoder` and `Decoder` implementations for
580-
`byte[]`, `ByteBuffer`, `DataBuffer`, `Resource`, and `String`. The `spring-web` module
581-
adds ``Encoder``'s and ``Decoder``'s for Jackson JSON, Jackson Smile, and JAXB2.
582-
The `spring-web` module also contains some web-specific readers and writers for
583-
server-sent events, form data, and multipart requests.
584-
585-
To configure or customize the readers and writers to use, applications will typically use
586-
`ClientCodecConfigurer` or `ServerCodecConfigurer`.
587-
588-
589-
[[webflux-codecs-jackson]]
590-
==== Jackson
591-
592-
The decoder relies on Jackson's non-blocking, byte array parser to parse a stream of byte
593-
chunks into a `TokenBuffer` stream, which can then be turned into Objects with Jackson's
594-
`ObjectMapper`. JSON and https://github.com/FasterXML/smile-format-specification[Smile]
595-
(binary JSON) data formats are currently supported.
596-
597-
The encoder processes a `Publisher<?>` as follows:
598-
599-
* if the `Publisher` is a `Mono` (i.e. single value), the value is encoded when available.
600-
* if media type is `application/stream+json` for JSON or `application/stream+x-jackson-smile`
601-
for Smile, each value produced by the `Publisher` is encoded individually (and followed
602-
by a new line in JSON).
603-
* otherwise all items from the `Publisher` are gathered in with `Flux#collectToList()`
604-
and the resulting collection is encoded as an array.
605-
606-
As a special case to the above rules the `ServerSentEventHttpMessageWriter` feeds items
607-
emitted from its input `Publisher` individually into the `Jackson2JsonEncoder` as a
608-
`Mono<?>`.
609-
610-
Note that both the Jackson JSON encoder and decoder explicitly back out of rendering
611-
elements of type `String`. Instead ``String``'s are treated as low level content, (i.e.
612-
serialized JSON) and are rendered as-is by the `CharSequenceEncoder`. If you want a
613-
`Flux<String>` rendered as a JSON array, you'll have to use `Flux#collectToList()` and
614-
provide a `Mono<List<String>>` instead.
615-
616-
617-
[[webflux-codecs-streaming]]
618-
==== HTTP Streaming
619-
[.small]#<<web.adoc#mvc-ann-async-http-streaming,Same in Spring MVC>>#
620-
621-
When a multi-value, reactive type such as `Flux` is used for response rendering, it may
622-
be collected to a `List` and rendered as a whole (e.g. JSON array), or it may be treated
623-
as an infinite stream with each item flushed immediately. The determination for which is
624-
which is made based on content negotiation and the selected media type which may imply a
625-
streaming format (e.g. "text/event-stream", "application/stream+json"), or not
626-
(e.g. "application/json").
627-
628-
When streaming to the HTTP response, regardless of the media type (e.g. text/event-stream,
629-
application/stream+json), it is important to send data periodically, since the write would
630-
fail if the client has disconnected. The send could take the form of an empty
631-
(comment-only) SSE event, or any other data that the other side would have to interpret as
632-
a heartbeat and ignore.
633-
634-
635-
636557
[[webflux-filters]]
637558
=== Filters
638559
[.small]#<<web.adoc#filters,Same in Spring MVC>>#
@@ -717,6 +638,80 @@ Below are the available `WebExceptionHandler` implementations:
717638

718639

719640

641+
[[webflux-codecs]]
642+
=== Codecs
643+
[.small]#<<integration.adoc#rest-message-conversion,Same in Spring MVC>>#
644+
645+
{api-spring-framework}/http/codec/HttpMessageReader.html[HttpMessageReader] and
646+
{api-spring-framework}/http/codec/HttpMessageWriter.html[HttpMessageWriter] are contracts
647+
for encoding and decoding HTTP request and response content via non-blocking I/O with
648+
(Rective Streams) back pressure.
649+
650+
{api-spring-framework}/core/codec/Encoder.html[Encoder] and
651+
{api-spring-framework}/core/codec/Decoder.html[Decoder] are contracts for encoding and
652+
decoding content, independent of HTTP. They can be wrapped with `EncoderHttpMessageWriter`
653+
or `DecoderHttpMessageReader` and used for web processing.
654+
655+
All codecs are for client or server side use. All build on
656+
{api-spring-framework}/core/io/buffer/DataBuffer.html[DataBuffer] which abstracts byte
657+
buffer representations such as the Netty `ByteBuf` or `java.nio.ByteBuffer` (see
658+
<<core#databuffers, Data Buffers and Codecs>> for more details). `ClientCodecConfigurer`
659+
and `ServerCodecConfigurer` are typically used to configure and customize the codecs to
660+
use in an application.
661+
662+
The `spring-core` module has encoders and decoders for `byte[]`, `ByteBuffer`, `DataBuffer`,
663+
`Resource`, and `String`. The `spring-web` module adds encoders and decoders for Jackson
664+
JSON, Jackson Smile, JAXB2, along with other web-specific HTTP message readers and writers
665+
for form data, multipart requests, and server-sent events.
666+
667+
668+
[[webflux-codecs-jackson]]
669+
==== Jackson
670+
671+
The decoder relies on Jackson's non-blocking, byte array parser to parse a stream of byte
672+
chunks into a `TokenBuffer` stream, which can then be turned into Objects with Jackson's
673+
`ObjectMapper`. JSON and https://github.com/FasterXML/smile-format-specification[Smile]
674+
(binary JSON) data formats are currently supported.
675+
676+
The encoder processes a `Publisher<?>` as follows:
677+
678+
* if the `Publisher` is a `Mono` (i.e. single value), the value is encoded when available.
679+
* if media type is `application/stream+json` for JSON or `application/stream+x-jackson-smile`
680+
for Smile, each value produced by the `Publisher` is encoded individually (and followed
681+
by a new line in JSON).
682+
* otherwise all items from the `Publisher` are gathered in with `Flux#collectToList()`
683+
and the resulting collection is encoded as an array.
684+
685+
As a special case to the above rules the `ServerSentEventHttpMessageWriter` feeds items
686+
emitted from its input `Publisher` individually into the `Jackson2JsonEncoder` as a
687+
`Mono<?>`.
688+
689+
Note that both the Jackson JSON encoder and decoder explicitly back out of rendering
690+
elements of type `String`. Instead ``String``'s are treated as low level content, (i.e.
691+
serialized JSON) and are rendered as-is by the `CharSequenceEncoder`. If you want a
692+
`Flux<String>` rendered as a JSON array, you'll have to use `Flux#collectToList()` and
693+
provide a `Mono<List<String>>` instead.
694+
695+
696+
[[webflux-codecs-streaming]]
697+
==== HTTP Streaming
698+
[.small]#<<web.adoc#mvc-ann-async-http-streaming,Same in Spring MVC>>#
699+
700+
When a multi-value, reactive type such as `Flux` is used for response rendering, it may
701+
be collected to a `List` and rendered as a whole (e.g. JSON array), or it may be treated
702+
as an infinite stream with each item flushed immediately. The determination for which is
703+
which is made based on content negotiation and the selected media type which may imply a
704+
streaming format (e.g. "text/event-stream", "application/stream+json"), or not
705+
(e.g. "application/json").
706+
707+
When streaming to the HTTP response, regardless of the media type (e.g. text/event-stream,
708+
application/stream+json), it is important to send data periodically, since the write would
709+
fail if the client has disconnected. The send could take the form of an empty
710+
(comment-only) SSE event, or any other data that the other side would have to interpret as
711+
a heartbeat and ignore.
712+
713+
714+
720715

721716
[[webflux-dispatcher-handler]]
722717
== DispatcherHandler
@@ -2532,6 +2527,11 @@ Javadoc for more details.
25322527

25332528

25342529

2530+
include::webflux-functional.adoc[leveloffset=+1]
2531+
2532+
2533+
2534+
25352535
[[webflux-uri-building]]
25362536
== URI Links
25372537
[.small]#<<web.adoc#mvc-uri-building,Same in Spring MVC>>#
@@ -2544,11 +2544,6 @@ include::web-uris.adoc[leveloffset=+2]
25442544

25452545

25462546

2547-
include::webflux-functional.adoc[leveloffset=+1]
2548-
2549-
2550-
2551-
25522547
include::webflux-cors.adoc[leveloffset=+1]
25532548

25542549

0 commit comments

Comments
 (0)