Spring WebFlux 全异步响应式框架

简介

WebFlux 是一种全异步类的响应式框架,现在已被Spring 归到另一类与 Servlet 同级的Web框架,为了向下兼容,WebFlux 在基础上依然支持 SpringMVC 的部分开发逻辑,但建议使用 Flux 风格的开发逻辑。

WebFlux 是有别于 Servlet 框架外独立开发的一种新的服务器请求框架,因此它严格来说不再使用 Servlet 的接口逻辑,而是使用了属于Flux 的接口逻辑。

具体与 Servlet 的底层逻辑区别如下:

 

引入WebFlux

我们可以直接依赖WebFlux进行全过程的 Web 服务开发,所以我们不再需要引入 spring-boot-starter-web 依赖,取而代之的是 spring-boot-starter-webflux 依赖。

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-webflux</artifactId>
        </dependency>

另外,Flux 框架默认使用 Netty 而非 Tomcat 了,虽然像 Tomcat,Underton 这些服务器在后期都增加了对 Flux 的支持,但是依然不及 Netty 的原生 Flux 支持,所以基本都使用 Netty 作为 Flux 服务器容器。

 

开发第一个 Flux 请求

在 Controller 请求上,Flux 与 Servlet 基本无异,虽然在响应请求方面,Flux 支持任意数据类型返回,但是 Flux 建议使用 Mono<> 或 Flux<> 这类对象对数据进行封装返回。

@RestController
public class HelloController {

    @GetMapping(value = "/index")
    public Mono<String> index(@RequestParam(value = "key",required = false,defaultValue = "hello") String key){

        System.out.println("收到请求参数:"+key);

        // 对数据进行封装,并返回,当然依然可以使用以往的其它对象直接返回也行
        return Mono.just(key);
    }

}

 

SSE 服务器推送响应

SSE,又称 Server Send Event,服务器发送事件,它可以使浏览器在一次请求当中,持续的接收服务器发来的分块数据,边接收边渲染网页,而不是每一次浏览器都要完全接收服务器的数据后才响应网页

在使用 SSE 之前,我们需要靠诉浏览器 header,我们响应的数据是 stream 类型的,可以在 @GetMapping 中指定 header 文档类型

@GetMapping(value = "/index",produces = MediaType.TEXT_EVENT_STREAM_VALUE) // 这是其中之一种,用于推送文本的流类型

 

因为 Flux 是全异步的框架,所以不存在阻塞机制,数据什么时候处理完,就什么时候发送给浏览器,浏览器接收到一部分就渲染一部分。SSE 只有 Flux 框架才能做到

我们可以让 Flux 数据做延迟派发来模拟数据持续发送的情况:

    @GetMapping(value = "/index", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> index(@RequestParam(value = "key", required = false, defaultValue = "hello") String key) {

        /**
         * 创建原始数据
         * 让这些数据每500毫秒派发一次
         */
        Flux<String> data = Flux.range(1, 10)
                .delayElements(Duration.ofMillis(500))
                .map(v -> v + "-haha");


        return data;
    }

对于 Flux 来说,任务会每 500 毫秒才会派发一次,那么返回给浏览器,则是每500毫秒接收到一次响应数据。

 

严格来说,SSE 请求推送,是有一个专用的封装类型 ServerSendEvent 类来处理的,我们可以使用这个类来包装用于 SSE 的数据。

    @GetMapping(value = "/index", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<ServerSentEvent<String>> index(@RequestParam(value = "key", required = false, defaultValue = "hello") String key) {

        /**
         * 创建原始数据
         * 让这些数据每500毫秒派发一次
         */
        Flux<ServerSentEvent<String>> data = Flux.range(1, 10)
                .delayElements(Duration.ofMillis(500))
                .map(v->{
                    return ServerSentEvent
                            .builder(v+"-data")
                            .id(v+"-id")
                            .comment(v+"-comment")
                            .event(v+"event")
                            .build();
                });
        

        return data;
    }

 

 

效果:

 

注解开发

目标方法传参

对于在业务方法中,WebFlux 会给我们传入以下的参数:

  • ServerWebExchange
    • 封装了请求和响应对象的对象; 自定义获取数据、自定义响应。它与 Servlet 不同的是,Servlet 提供 ServletHttpRequest 和 ServletHttpResponse。而 WebFlux 中只提供了 ServerWebExchange ,而 ServerWebExchange 中则已包含 ServerHttpRequesst 和 ServerHttpResponse
  • ServerHttpRequest, ServerHttpResponse
    • 请求、响应对象
  • WebSession
    • 访问Session对象
  • org.springframework.http.HttpMethod
    • 请求方式
  • java.util.Locale
    • 国际化
  • java.util.TimeZone + java.time.ZoneId
    • 时区
  • @PathVariable
    • 路径变量
  • @MatrixVariable
    • 矩阵变量
  • @RequestParam
    • 请求参数
  • @RequestHeader
    • 请求头
  • @CookieValue
    • 获取Cookie
  • @RequestBody
    • 获取请求体,Post、文件上传
  • HttpEntity<B>
    • 封装后的请求对象
  • @RequestPart
    • 获取文件上传的数据 multipart/form-data
  • java.util.Map, org.springframework.ui.Model, and org.springframework.ui.ModelMap
    • Map、Model、ModelMap 与以前的ModelAndView 类似的 Model 数据模型
  • Errors, BindingResult
    • 数据校验,封装错误
  • @RequestAttribute
    • 转发请求的请求域数据
  • 其它参数
    • 所有对象都能作为参数:
    • 1、基本类型 ,等于标注@RequestParam
    • 2、对象类型,等于标注 @ModelAttribute

 

返回值写法

WebFlux 支持的业务返回值,以下列表中的返回值,会被WebFlux 识别为特殊处理的类型,

  • @ResponseBody
    • 把响应数据写出去,如果是对象,可以自动转为json
  • HttpEntity<B> , ResponseEntity<B>
    • ResponseEntity:支持快捷自定义响应内容
  • HttpHeaders
    • 没有响应内容,只有响应头
  • ErrorResponse
    • 快速构建错误响应,与 ProblemDetail 差不多的用于构建异常信息返回类,底层调用 ProblemDetail
  • ProblemDetail
    • SpringBoot3 中新出的一种用于构建异常信息返回类,可以使用这个类来构建错误代码和错误原因,如 code:404 原因:Not Found等
  • String
    • 就是和以前的使用规则一样;当使用模板引擎时,String 的返回值会被识别为一个html模板的文件名。forward: 转发到一个地址 redirect: 重定向到一个地址
  • View
    • 直接返回视图对象
  • java.util.Map, org.springframework.ui.Model
    • 与原来的 Servlet 框架一样
  • @ModelAttribute
    • 与原来的 Servlet 框架一样
  • Rendering
    • WebFlux 新增的功能,当使用模板引擎时,可以使用 Rendering 类创建响应页面
  • void
    • 仅代表响应完成信号,在返回值中为 Mono<Void> 时,则相当于返回一个只有成功信号,无数据的Mono流
  • 其它参数
    • 未在上述列表的其他返回值,都会当成给页面的数据

 

文件上传

在以往的 Servlet 框架中,使用 MultipartFile 类型接收上传的文件,而在 WebFlux 中会有所区别

使用 @RequestPart 接收文件上传的参数名,使用 FilePart 来用于接收文件

@PostMapping("/")
public String handle(@RequestPart("meta-data") Part metadata, @RequestPart("file-data") FilePart file) {
// ...
}

当然也可以使用 MultipartFile 来接收,但是 FilePart 与 MultipartFile  有区别,MultipartFile 依然是阻塞式的,而 FilePart  使用无拷贝式,性能会更快,更适合在 WebFlux 这种响应式编程框中使用。

 

RequestContext

 

WebFluxConfigurer 自定义配置

 

Filter 过滤器

 

 

如果您喜欢本站,点击这儿不花一分钱捐赠本站

这些信息可能会帮助到你: 下载帮助 | 报毒说明 | 进站必看

修改版本安卓软件,加群提示为修改者自留,非本站信息,注意鉴别

THE END
分享
二维码
打赏
海报
Spring WebFlux 全异步响应式框架
简介 WebFlux 是一种全异步类的响应式框架,现在已被Spring 归到另一类与 Servlet 同级的Web框架,为了向下兼容,WebFlux 在基础上依然支持 SpringMVC 的部分开发逻辑,但建议使用 Flux 风格……
<<上一篇
下一篇>>