Skip to content

Commit 9d5a25e

Browse files
committed
Proper WebFlux reference and MVC reference updates
Pending -- WebSocket, WebTestClient, more details around annotation processing, exception handling, and view resolution. Issue: SPR-15149, SPR-16009
1 parent 41b53de commit 9d5a25e

File tree

10 files changed

+2262
-1387
lines changed

10 files changed

+2262
-1387
lines changed
-70.2 KB
Binary file not shown.

src/docs/asciidoc/index.adoc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ IoC container, with any web framework on top, but you can also use only the
1212
<<data-access.adoc#jdbc-introduction,JDBC abstraction layer>>. The Spring Framework supports declarative
1313
transaction management, remote access to your logic through RMI or web services, and various
1414
options for persisting your data.
15-
It offers full-featured web frameworks such as <<web.adoc#mvc-introduction,Spring MVC>>
16-
and <<reactive-web.adoc#webflux, Spring WebFlux>>; and it enables you to
15+
It offers full-featured web frameworks such as <<web.adoc#mvc,Spring Web MVC>>
16+
and <<web-reactive.adoc#webflux, Spring WebFlux>>; and it enables you to
1717
integrate <<core.adoc#aop-introduction,AOP>> transparently into your software.
1818

1919
This document is a reference guide to Spring Framework features. Questions on the
@@ -29,7 +29,7 @@ This reference document provides the following sections:
2929
3030
* <<data-access.adoc#spring-data-tier,Data access and transaction management>>
3131
32-
* The Web on <<web.adoc#spring-web,Servlet>> or <<reactive-web.adoc#spring-webflux,Reactive>> stacks
32+
* The Web on <<web.adoc#spring-web,Servlet>> or <<web-reactive.adoc#spring-webflux,Reactive>> stacks
3333
3434
* <<kotlin.adoc#kotlin,Kotlin support>>
3535

src/docs/asciidoc/integration.adoc

Lines changed: 2 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1369,68 +1369,8 @@ and writes the media type supported by the Java I/O API.
13691369
[[rest-async-resttemplate]]
13701370
==== Async RestTemplate
13711371

1372-
Web applications often need to query external REST services those days. The very nature of
1373-
HTTP and synchronous calls can lead up to challenges when scaling applications for those
1374-
needs: multiple threads may be blocked, waiting for remote HTTP responses.
1375-
1376-
`AsyncRestTemplate` and <<rest-resttemplate>>'s APIs are very similar; see
1377-
<<rest-overview-of-resttemplate-methods-tbl>>. The main difference between those APIs is
1378-
that `AsyncRestTemplate` returns
1379-
{api-spring-framework}/util/concurrent/ListenableFuture.html[`ListenableFuture`]
1380-
wrappers as opposed to concrete results.
1381-
1382-
The previous `RestTemplate` example translates to:
1383-
1384-
[source,java,indent=0]
1385-
[subs="verbatim,quotes"]
1386-
----
1387-
// async call
1388-
Future<ResponseEntity<String>> futureEntity = template.getForEntity(
1389-
"http://example.com/hotels/{hotel}/bookings/{booking}", String.class, "42", "21");
1390-
1391-
// get the concrete result - synchronous call
1392-
ResponseEntity<String> entity = futureEntity.get();
1393-
----
1394-
1395-
{api-spring-framework}/util/concurrent/ListenableFuture.html[`ListenableFuture`]
1396-
accepts completion callbacks:
1397-
1398-
[source,java,indent=0]
1399-
[subs="verbatim,quotes"]
1400-
----
1401-
ListenableFuture<ResponseEntity<String>> futureEntity = template.getForEntity(
1402-
"http://example.com/hotels/{hotel}/bookings/{booking}", String.class, "42", "21");
1403-
1404-
// register a callback
1405-
futureEntity.addCallback(new ListenableFutureCallback<ResponseEntity<String>>() {
1406-
@Override
1407-
public void onSuccess(ResponseEntity<String> entity) {
1408-
//...
1409-
}
1410-
1411-
@Override
1412-
public void onFailure(Throwable t) {
1413-
//...
1414-
}
1415-
});
1416-
----
1417-
1418-
[NOTE]
1419-
====
1420-
The default `AsyncRestTemplate` constructor registers a
1421-
{api-spring-framework}/core/task/SimpleAsyncTaskExecutor.html[`SimpleAsyncTaskExecutor`
1422-
] for executing HTTP requests.
1423-
When dealing with a large number of short-lived requests, a thread-pooling TaskExecutor
1424-
implementation like
1425-
{api-spring-framework}/scheduling/concurrent/ThreadPoolTaskExecutor.html[`ThreadPoolTaskExecutor`]
1426-
may be a good choice.
1427-
====
1428-
1429-
See the
1430-
{api-spring-framework}/util/concurrent/ListenableFuture.html[`ListenableFuture` javadocs]
1431-
and
1432-
{api-spring-framework}/web/client/AsyncRestTemplate.html[`AsyncRestTemplate` javadocs]
1433-
for more details.
1372+
The `AsyncRestTemplate` is deprecated.
1373+
Please use the <<web-reactive.adoc#webflux-client,WebClient>> instead.
14341374

14351375

14361376

src/docs/asciidoc/kotlin.adoc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -261,7 +261,7 @@ for more details and up-to-date information.
261261

262262
Spring Framework now comes with a
263263
{doc-root}/spring-framework/docs/{spring-version}/kdoc-api/spring-framework/org.springframework.web.reactive.function.server/-router-function-dsl/[Kotlin routing DSL]
264-
that allows one to leverage the <<reactive-web#webflux-fn,WebFlux functional
264+
that allows one to leverage the <<web-reactive#webflux-fn,WebFlux functional
265265
API>> for writing clean and idiomatic Kotlin code:
266266

267267
[source,kotlin]
@@ -583,7 +583,7 @@ https://spring.io/blog/2017/08/01/spring-framework-5-kotlin-apis-the-functional-
583583
=== Choosing the web flavor
584584

585585
Spring Framework now comes with 2 different web stacks: <<web#mvc,Spring MVC>> and
586-
<<reactive-web#spring-web-reactive,Spring WebFlux>>.
586+
<<web-reactive#spring-web-reactive,Spring WebFlux>>.
587587

588588
Spring WebFlux is recommended if one wants to create applications that will deal with latency,
589589
long-lived connections, streaming scenarios or simply if one wants to use the web functional

src/docs/asciidoc/reactive-web.adoc

Lines changed: 0 additions & 62 deletions
This file was deleted.

src/docs/asciidoc/web-reactive.adoc

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
[[spring-web-reactive]]
2+
= Web on Reactive Stack
3+
:doc-root: https://docs.spring.io
4+
:api-spring-framework: {doc-root}/spring-framework/docs/{spring-version}/javadoc-api/org/springframework
5+
:toc: left
6+
:toclevels: 4
7+
:docinfo1:
8+
9+
This part of the documentation covers support for reactive stack, web applications built on a
10+
http://www.reactive-streams.org/[Reactive Streams] API to run on top of non-blocking
11+
servers such as Netty, Undertow, and Servlet 3.1+ containers. Individual chapters cover
12+
<<webflux-module, Spring WebFlux>> and its <<webflux-fn,functional programming model>>.
13+
For Servlet stack, web applications, to go <<web.adoc#spring-web,Web on Servlet Stack>>.
14+
15+
include::web/webflux.adoc[leveloffset=+1]

src/docs/asciidoc/web.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
This part of the documentation covers support for Servlet stack, web applications built on the
1010
Servlet API and deployed to Servlet containers. Individual chapters include <<mvc,Spring MVC>>,
1111
<<mvc-view,View Technologies>>, <<mvc-cors,CORS Support>>, and <<websocket,WebSocket Support>>.
12-
The next section covers support for <<reactive-web.adoc#spring-reactive-web,reactive web>> applications.
12+
For reactive stack, web applications, go to <<web-reactive.adoc#spring-web-reactive,Web on Reactive Stack>>.
1313

1414
include::web/webmvc.adoc[leveloffset=+1]
1515

src/docs/asciidoc/web/webflux-functional.adoc

Lines changed: 30 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,25 @@
11
[[webflux-fn]]
2-
= Functional Programming Model
2+
= Functional Endpoints
3+
4+
Spring WebFlux provides a lightweight, functional programming model where functions
5+
are used to route and handle requests and where contracts are designed for immutability.
6+
It is an alternative to the annotated-based programming model but runs on the same
7+
<<web-reactive.adoc#webflux-reactive-spring-web>> foundation
8+
39

410
[[webflux-fn-handler-functions]]
5-
== HandlerFunctions
11+
== HandlerFunction
612

713
Incoming HTTP requests are handled by a **`HandlerFunction`**, which is essentially a function that
814
takes a `ServerRequest` and returns a `Mono<ServerResponse>`. The annotation counterpart to a
9-
handler function would be a method with `@RequestMapping`.
15+
handler function is an `@RequestMapping` method.
1016

1117
`ServerRequest` and `ServerResponse` are immutable interfaces that offer JDK-8 friendly access
12-
to the underlying HTTP messages. Both are fully reactive by
13-
building on top of Reactor: the request expose the body as `Flux` or `Mono`; the response accepts
14-
any http://www.reactive-streams.org[Reactive Streams] `Publisher` as body.
18+
to the underlying HTTP messages with http://www.reactive-streams.org[Reactive Streams]
19+
non-blocking back pressure. The request exposes the body as Reactor `Flux` or `Mono`
20+
types; the response accepts any Reactive Streams `Publisher` as body (see
21+
<<web-reactive.adoc#webflux-reactive-libraries,Reactive Libraries>>).
22+
1523

1624
`ServerRequest` gives access to various HTTP request elements:
1725
the method, URI, query parameters, and -- through the separate `ServerRequest.Headers` interface
@@ -26,7 +34,7 @@ contains JSON, or JAXB if XML).
2634

2735
Flux<Person> people = request.bodyToFlux(Person.class);
2836

29-
The two methods above (`bodyToMono` and `bodyToFlux`) are, in fact, convenience methods that use the
37+
The above -- `bodyToMono` and `bodyToFlux`, are, in fact, convenience methods that use the
3038
generic `ServerRequest.body(BodyExtractor)` method. `BodyExtractor` is
3139
a functional strategy interface that allows you to write your own extraction logic, but common
3240
`BodyExtractor` instances can be found in the `BodyExtractors` utility class. So, the above
@@ -43,7 +51,8 @@ a JSON content-type, and a body:
4351
Mono<Person> person = ...
4452
ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(person);
4553

46-
And here is how to build a response with a 201 Created status, Location header, and empty body:
54+
And here is how to build a response with a 201 CREATED status, a `"Location"` header, and
55+
empty body:
4756

4857
URI location = ...
4958
ServerResponse.created(location).build();
@@ -111,7 +120,7 @@ variable `id`. We retrieve that `Person` via the repository, and create a JSON r
111120
found. If it is not found, we use `switchIfEmpty(Mono<T>)` to return a 404 Not Found response.
112121

113122
[[webflux-fn-router-functions]]
114-
== RouterFunctions
123+
== RouterFunction
115124

116125
Incoming requests are routed to handler functions with a **`RouterFunction`**, which is a function
117126
that takes a `ServerRequest`, and returns a `Mono<HandlerFunction>`. If a request matches a
@@ -172,43 +181,23 @@ Most of the predicates found in `RequestPredicates` are compositions.
172181
For instance, `RequestPredicates.GET(String)` is a composition of
173182
`RequestPredicates.method(HttpMethod)` and `RequestPredicates.path(String)`.
174183

175-
[[webflux-fn-running]]
176-
=== Running a Server
177-
178-
Now there is just one piece of the puzzle missing: running a router function in an HTTP server.
179-
You can convert a router function into a `HttpHandler` by using
180-
`RouterFunctions.toHttpHandler(RouterFunction)`.
181-
The `HttpHandler` allows you to run on a wide variety of reactive runtimes: Reactor Netty,
182-
Servlet 3.1+, and Undertow.
183-
Here is how we run a router function in Reactor Netty, for instance:
184184

185-
[source,java,indent=0]
186-
[subs="verbatim,quotes"]
187-
----
188-
RouterFunction<ServerResponse> route = ...
189-
HttpHandler httpHandler = RouterFunctions.toHttpHandler(route);
190-
ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(httpHandler);
191-
HttpServer server = HttpServer.create(HOST, PORT);
192-
server.newHandler(adapter).block();
193-
----
185+
[[webflux-fn-running]]
186+
== Running a server
194187

195-
For Tomcat it looks like this:
188+
How do you run a router function in an HTTP server? A simple option is to convert a
189+
router function to an `HttpHandler` via `RouterFunctions.toHttpHandler(RouterFunction)`.
190+
The `HttpHandler` can then be used with a number of servers adapters.
191+
See <<web-reactive.adoc#webflux-httphandler,HttpHandler>> for server-specific
192+
instructions.
196193

197-
[source,java,indent=0]
198-
[subs="verbatim,quotes"]
199-
----
200-
RouterFunction<ServerResponse> route = ...
201-
HttpHandler httpHandler = RouterFunctions.toHttpHandler(route);
202-
HttpServlet servlet = new ServletHttpHandlerAdapter(httpHandler);
203-
Tomcat server = new Tomcat();
204-
Context rootContext = server.addContext("", System.getProperty("java.io.tmpdir"));
205-
Tomcat.addServlet(rootContext, "servlet", servlet);
206-
rootContext.addServletMapping("/", "servlet");
207-
tomcatServer.start();
208-
----
194+
it is also possible to run with a
195+
<<web-reactive.adoc#webflux-dispatcher-handler,DispatcherHandler>> setup -- side by side
196+
with annotated controllers. The easiest way to do that is through the
197+
<<web-reactive.adoc#webflux-config>> which creates the necessary configuration to
198+
handle requests with router and handler functions.
209199

210200

211-
// TODO: DispatcherHandler
212201

213202
[[webflux-fn-handler-filter-function]]
214203
== HandlerFilterFunction

0 commit comments

Comments
 (0)