diff --git a/spring/webflux/spring webflux.md b/spring/webflux/spring webflux.md index 9021b13..ad2c776 100644 --- a/spring/webflux/spring webflux.md +++ b/spring/webflux/spring webflux.md @@ -37,6 +37,10 @@ - [Overview](#overview) - [Immutable](#immutable) - [Router Function](#router-function) + - [HandlerFunction](#handlerfunction) + - [Server Request](#server-request) + - [ServerResponse](#serverresponse) + - [Handler Class](#handler-class) # Spring Webflux @@ -542,4 +546,90 @@ public class PersonHandler { - `RouterFunctions.toHttpHandler(RouterFunction)` - `RouterFunctions.toHttpHandler(RouterFunction, HandlerStrategies)` +### HandlerFunction +`ServerRequest`和`ServerResponse`为不可变接口,两者都对body stream提供Reactive Stream back pressure。 +- 其中,request body通过Reactor `Flux`或`Mono`表示 +- response body可以通过任何`Reactive Stream Publisher`进行表示,包括`Flux`和`Mono` + +### Server Request +ServerRequest提供了对如下内容的访问: +- http method +- uri +- headers +- query params +- body + +如下示例展示了如何将请求体转化为`Mono/Flux`类型: +```java +Mono string = request.bodyToMono(String.class); + +Flux people = request.bodyToFlux(Person.class); +``` + +如下示例展示了如何访问formdata: +```java +Mono> map = request.formData(); +``` + +如下示例展示了如何访问multipart data: +```java +Mono> map = request.multipartData(); +``` + +访问multipart数据内容的示例如下所示: +```java +Flux allPartEvents = request.bodyToFlux(PartEvent.class); +allPartsEvents.windowUntil(PartEvent::isLast) + .concatMap(p -> p.switchOnFirst((signal, partEvents) -> { + if (signal.hasValue()) { + PartEvent event = signal.get(); + if (event instanceof FormPartEvent formEvent) { + String value = formEvent.value(); + // handle form field + } + else if (event instanceof FilePartEvent fileEvent) { + String filename = fileEvent.filename(); + Flux contents = partEvents.map(PartEvent::content); + // handle file upload + } + else { + return Mono.error(new RuntimeException("Unexpected event: " + event)); + } + } + else { + return partEvents; // either complete or error signal + } + })); +``` +### ServerResponse +ServerResponse类提供了对http返回内容的访问,由于ServerResponse是不可变的,故而可以通过`build`方法来创建ServerResponse。 + +如下示例展示了ServerResponse的使用 +```java +Mono person = ... +ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(person, Person.class); + +URI location = ... +ServerResponse.created(location).build(); +``` + +同时,在构建响应体时,支持传递hint参数来控制body被序列化和反序列化的方式,示例如下: +```java +ServerResponse.ok().hint(Jackson2CodecSupport.JSON_VIEW_HINT, MyJacksonView.class).body(...); +``` + +### Handler Class +可以将HandlerFunction写为lambda的形式,示例如下: +```java +HandlerFunction helloWorld = + request -> ServerResponse.ok().bodyValue("Hello World"); +``` + + + + + + + +