响应式编程WebFlux基础API

WebFlux的工作流程

在WebFlux中,主要的组件包括:

  • Reactor: Reactor是WebFlux底层使用的响应式编程库,提供了MonoFlux这两种响应式类型,分别用于表示0-1个和0-N个异步序列元素。
  • WebHandler: 是处理请求的核心接口,所有的请求都会被分配给一个WebHandler来处理。
  • HandlerMapping: 用于将请求映射到对应的WebHandler
  • HandlerAdapter: 用于适配WebHandler的执行,使其能够处理请求并返回响应。
  • WebFilter: 类似于Servlet中的Filter,可以在请求处理前后进行拦截和处理。
  • ServerResponseServerRequest: 分别代表HTTP的响应和请求,在WebFlux中用于处理非阻塞的请求和响应。
  • RouterFunction: 用于声明式地定义路由规则,将请求映射到处理器函数。

工作流程图

Request
Dispatch
Map to
Filter
Process
Response
Return
Use
Async Processing
Client
Server
HandlerMapping
WebHandler
WebFilter
HandlerAdapter
ServerResponse
Reactor

在这个流程中:

  1. 客户端发送请求到服务器。
  2. 服务器接收到请求,并将其分发给HandlerMapping
  3. HandlerMapping根据请求信息将其映射到对应的WebHandler
  4. WebFilter可以在请求到达WebHandler之前或之后进行拦截和处理。
  5. WebHandler处理请求,可能会使用Reactor库中的MonoFlux进行异步处理。
  6. HandlerAdapterWebHandler的处理结果适配成服务器可以发送的响应。
  7. ServerResponse将响应返回给客户端。

WebFlux核心API

1. HttpHandler与HttpServer

HttpHandler

HttpHandler是WebFlux中处理HTTP请求的核心接口之一。它代表一个能够处理HTTP请求并生成响应的组件。HttpHandler可以被看作是一个函数,接受一个HTTP请求并返回一个表示HTTP响应的Publisher。典型的HttpHandler可以是一个Lambda表达式或一个实现了接口的类。可用于 Reactor Netty 的适配器, Undertow、Tomcat、Jetty 和任何 Servlet 容器。

HttpServer

HttpServer是Reactor Netty提供的一个用于构建HTTP服务器的类。它允许你配置服务器的主机名、端口、SSL支持等信息。

public class SimpleHttpHandlerServerExample {public static void main(String[] args) throws IOException {HttpHandler httpHandler = RouterFunctions.toHttpHandler(RouterFunctions.route().GET("/hello", request -> ServerResponse.ok().bodyValue("Hello, WebFlux!")).build());ReactorHttpHandlerAdapter adapter = new ReactorHttpHandlerAdapter(httpHandler);//启动Netty服务器HttpServer.create().host("localhost").port(8080).handle(adapter) //用指定的处理器处理请求.bindNow(); //现在就绑定System.out.println("服务器启动完成....监听8080,接受请求");System.in.read();System.out.println("服务器停止....");}
}

测试

GET http://localhost:8080/hello 响应:Hello, WebFlux!

2. DispatcherHandler

前中讲到WebFlux的工作流程第5步中WebHandler用于处理请求

在 Spring WebFlux 中,DispatcherHandler 实现了 WebHandler 接口,因此 DispatcherHandlerWebHandler 的一种具体实现。 WebHandler 接口定义了处理 HTTP 请求的方法,而 DispatcherHandler 实现了这个接口,提供了处理请求的具体实现。

WebHandler 接口的主要方法是 handle,用于处理 HTTP 请求。DispatcherHandler 通过实现这个接口,提供了对请求的分发和处理的支持。下面是 WebHandler 接口的声明:

public interface WebHandler {Mono<Void> handle(ServerWebExchange exchange);
}

DispatcherHandler 通过实现 WebHandler 接口,定义了处理请求的具体逻辑。在 DispatcherHandler 中,handle 方法被实现为请求的分发和处理,如代码所示。

@Override
public Mono<Void> handle(ServerWebExchange exchange) {// 如果 handlerMappings 为 null,返回一个包含错误信息的 Monoif (this.handlerMappings == null) {return createNotFoundError();}// 如果是预检请求(CORS pre-flight request),处理预检请求if (CorsUtils.isPreFlightRequest(exchange.getRequest())) {return handlePreFlight(exchange);}// 从 handlerMappings 中获取处理器函数return Flux.fromIterable(this.handlerMappings)// 依次尝试每个 HandlerMapping,获取处理器函数(是开发者编写的处理器函数,Controller中的接口),也是工作流程中第3步.concatMap(mapping -> mapping.getHandler(exchange)) // 取第一个非空的处理器函数,如果都为空,则返回 createNotFoundError.next()// 如果获取处理器函数失败,也返回 createNotFoundError.switchIfEmpty(createNotFoundError())// 处理可能发生的错误,比如处理器函数执行时的异常.onErrorResume(ex -> handleDispatchError(exchange, ex))// 处理请求,传递 ServerWebExchange 和处理器函数.flatMap(handler -> handleRequestWith(exchange, handler));
}

所以,DispatcherHandlerWebHandler 的一种实现,用于实现对请求的分发和处理。在 Spring WebFlux 中,DispatcherHandler 是整个请求处理流程的核心组件之一。

WebFlux常用API

  1. RouterFunctions:
    RouterFunctions 是用于定义路由的主要接口。通过它,你可以定义请求的映射和处理。

    @Configuration
    public class MyRouterConfig {@Beanpublic RouterFunction<ServerResponse> myRoutes(MyHandler handler) {return RouterFunctions.route(GET("/api/resource/{id}"), handler::handleResource).andRoute(POST("/api/resource"), handler::createResource);}
    }
    
  2. HandlerFunction:
    HandlerFunction 用于处理请求,并返回响应。你需要为每个路由定义一个处理函数。

    @Component
    public class MyHandler {public Mono<ServerResponse> handleResource(ServerRequest request) {// 处理 GET 请求逻辑// 返回 Mono<ServerResponse>String resourceId = request.pathVariable("id");WebClient webClient = WebClient.create("http://localhost:8080");webClient.get().uri("/api/resource/{id}", 123).retrieve().bodyToMono(String.class).subscribe(response -> System.out.println("Response: " + response));// 处理逻辑return ServerResponse.ok().bodyValue("Resource ID: " + resourceId);}public Mono<ServerResponse> createResource(ServerRequest request) {// 处理 POST 请求逻辑// 返回 Mono<ServerResponse>return Mono.just("Hello, WebFlux!").flatMap(response -> ServerResponse.ok().bodyValue(response));}
    }
    
  3. ServerRequest 和 ServerResponse:
    ServerRequest 表示一个 HTTP 请求,而 ServerResponse 表示一个 HTTP 响应。在处理函数中,你可以通过这两个对象来获取请求信息和构建响应。

        public Mono<ServerResponse> handleResource(ServerRequest request) {// 处理 GET 请求逻辑// 返回 Mono<ServerResponse>String resourceId = request.pathVariable("id");WebClient webClient = WebClient.create("http://localhost:8080");webClient.get().uri("/api/resource/{id}", 123).retrieve().bodyToMono(String.class).subscribe(response -> System.out.println("Response: " + response));// 处理逻辑return ServerResponse.ok().bodyValue("Resource ID: " + resourceId);}
    
  4. Mono 和 Flux:
    MonoFlux 是 Reactor 框架中的概念,但在 Spring WebFlux 中也经常用到。Mono 用于表示包含零个或一个元素的异步序列,而 Flux 用于表示包含零个或多个元素的异步序列。

        public Mono<ServerResponse> createResource(ServerRequest request) {// 处理 POST 请求逻辑// 返回 Mono<ServerResponse>return Mono.just("Hello, WebFlux!").flatMap(response -> ServerResponse.ok().bodyValue(response));}
    
  5. WebClient:
    WebClient 是 Spring WebFlux 提供的用于进行 HTTP 请求的客户端。它支持异步和响应式编程。

        public Mono<ServerResponse> handleResource(ServerRequest request) {// 处理 GET 请求逻辑// 返回 Mono<ServerResponse>String resourceId = request.pathVariable("id");WebClient webClient = WebClient.create("http://localhost:8080");webClient.get().uri("/api/resource/{id}", 123).retrieve().bodyToMono(String.class).subscribe(response -> System.out.println("Response: " + response));// 处理逻辑return ServerResponse.ok().bodyValue("Resource ID: " + resourceId);}
    
  6. MediaType 和 Content-Type:
    MediaType 类用于表示媒体类型,而 Content-Type 则是 HTTP 请求和响应中用于指定实体主体的媒体类型。

    public Mono<ServerResponse> handleResource(ServerRequest request) {return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).bodyValue("{ \"message\": \"Hello, WebFlux!\" }");
    }
    
  7. ExceptionHandler:
    ExceptionHandler 用于全局处理异常,你可以通过实现 WebExceptionHandler 接口来自定义异常处理逻辑。

    @Component
    @Order(-2) // 定义处理器的顺序
    public class GlobalExceptionHandler implements WebExceptionHandler {@Overridepublic Mono<Void> handle(ServerWebExchange exchange, Throwable ex) {// 处理其他异常exchange.getResponse().setStatusCode(HttpStatus.INTERNAL_SERVER_ERROR);return exchange.getResponse().setComplete();}
    }
    

学习打卡day09:响应式编程WebFlux基础API

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/616401.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Git的简单使用说明

Git入门教程 git的最主要的作用&#xff1a;版本控制&#xff0c;协助开发 一.版本控制分类 ​​ 1.本地版本控制 ​​ 2.集中版本控制 ​​ 所有的版本数据都存在服务器上&#xff0c;用户的本地只有自己以前所同步的版本&#xff0c;如果不连网的话&#xff0c;用户就看不…

制作 Kali 可启动 USB 驱动器

Kali USB驱动器&#xff0c;轻松安全&#xff0c;获取最新镜像&#xff0c;开始强大的安全测试&#xff01; Kali 可启动 USB 驱动器的优点&#xff1a; 不会更改主机系统的硬盘驱动器或已安装的操作系统&#xff0c;并且要返回正常操作&#xff0c;您只需删除“Kali Live”U…

模型评估:超参数调优

对于很多算法工程师来说&#xff0c;超参数调优是一件非常头疼的事情。除了根据经验设定所谓的“合理值”之外&#xff0c;一般很难找到合理的方法去寻找超参数的最优取值。而与此同时&#xff0c;超参数对于模型效果的影响又至关重要。有没有一些可行的办法去进行超参数的调优…

Qt 6之七:学习资源

Qt 6之七&#xff1a;学习资源 Qt是一种跨平台的C应用程序开发框架&#xff0c;它提供了一套丰富的工具和库&#xff0c;可以帮助开发者快速构建跨平台的应用程序&#xff0c;用于开发图形用户界面&#xff08;GUI&#xff09;和非GUI应用程序。 Qt 6之一&#xff1a;简介、安…

全国(山东、安徽)职业技能大赛--信息安全管理与评估Apache配置评估题目+WP解析+环境

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【python】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏 == 养成习惯(一键三连)😋 🎉欢迎关注💗一起学习👍一起讨论⭐️一起进步…

小手也能用的高性能鼠标,自定义空间还挺高,雷柏VT9Pro mini上手

今年搭载PAW3395传感器的电竞鼠标很受欢迎&#xff0c;雷柏就出了不少型号&#xff0c;满足各种喜好的玩家选择&#xff0c;像是近期新出的搭载3395高定版的VT9Pro和VT9Pro mini&#xff0c;就在轻量化的基础上&#xff0c;满足了各种手型的玩家的使用需要&#xff0c;而且价格…

Whale 帷幄创始人叶生晅:AIGC 时代,营销的范式变了丨未来 AI 谈

「未来 AI 谈」是「Marteker 营销技术官」联合「Digital Frontier 首席数字官」共同发起的一档对话栏目&#xff0c;旨在探讨生成式 AI 的崛起对泛营销技术和营销自动化带来的影响&#xff0c;以期帮助全行业探索 AIGC 时代的新营销之路。 本期嘉宾&#xff1a;「Whale 帷幄」创…

Linux中DNS域名解析服务及实验

一、DNS介绍 1、DNS 是域名系统&#xff0c;应用层协议&#xff0c;是互联网的一项服务&#xff0c;是将域名转换成网络可以识别的IP地址&#xff0c;再通过IP地址访问主机。这种由文字组成的名称更容易记忆。 DNS是“域名系统"的英文缩写。它作为将域名和IP地址相互映…

如何提高匹配的精确度(多次学习)

我们工业自动化中&#xff0c;视觉软件匹配&#xff0c;都是学习一次&#xff0c;比如找到轮廓&#xff0c;旋转360度&#xff0c;也就是有360个轮廓&#xff0c;然后到图像中去找任意角度的目标。 这样的学习并不能一而概括全。 所以&#xff0c;我借鉴ai的方法&#xff0c;…

C语言:高地址和低地址、高字节与低字节、大小端模式的转换、存储顺序

https://blog.csdn.net/oqqHuTu12345678/article/details/82823890/ 和另外一篇栈的生长、存放顺序一样&#xff0c;一般描述栈的方向是相反的&#xff0c;即栈底在下&#xff0c;栈顶在上。注意大小端存储方式&#xff0c;简单讲小端是低字节低地址&#xff0c;高字节高地址&…

ERP管理平台—通用功能测试用例

ERP管理平台—通用功能测试用例 登录页面UI页面UI验证正确打开系统

C#超市管理系统源码

C#超市管理系统源码 功能齐全的超市管理系统&#xff0c;专门美化过UI 请先附加数据库&#xff0c;否则无法进入系统 默认拥有最高权限账户为经理&#xff0c;密码为admin 压缩包内有使用说明

Cdd诊断数据控中的zz rc yy

如上图所示的Cdd Candela Diagnostic Descriptions 诊断数据库会话定义中有许多的标识符缩写&#xff0c;如zz rc LL xx 等 其实这些字母没有意义&#xff0c;它们只是唯一地标识对话框中的组合组件。

snmp协议配置

引言 SNMP&#xff08;Simple Network Management Protocol&#xff09;是一种网络管理协议&#xff0c;用于管理和监控网络设备、操作系统和应用程序。它提供了一组用于检索和修改网络设备配置、监视设备状态和性能的标准化方法。 SNMP 是一个客户端-服务器协议&#xff0c;…

C++ 学习笔记之运算符重载+案例

目录 一、C 运算符重载 二、定义一个成员函数或全局函数 三、计算时间 1.计算时间差 2.时间加减 四、一个运算符重载实例 一、C 运算符重载 是一种特性&#xff0c;它允许程序员重新定义已有的运算符的行为&#xff0c;以适应自定义类型的操作。通过运算符重载&#xff0…

电商新趋势:解析养号的必要性及海外云手机运用攻略

在电商领域&#xff0c;什么最为关键&#xff1f;答案无疑是流量&#xff01;然而&#xff0c;如何以较低成本获取大量流量成为了许多电商从业者头疼的问题。虽然直接投放广告是一种方式&#xff0c;但在内卷的情况下效果越来越难以令人满意&#xff0c;高昂的广告费用也原来越…

Python如何对csv文件进行操作

csv是Comma-Separated Values的缩写&#xff0c;是用文本文件形式储存的表格数据&#xff0c;比如如下的表格&#xff1a; 就可以存储为csv文件&#xff0c;文件内容是&#xff1a; No.,Name,Age,Score1,mayi,18,99 2,jack,21,89 3,tom,25,95 4,rain,19,80 假设上述csv文件保存…

【C】预处理指令 #define, #include, #if...#elif...#else...#endif

目录 C 预处理1 #define1&#xff09;基本语法2&#xff09;常量宏3&#xff09;表达式宏4&#xff09;语句宏5&#xff09;代码块宏6&#xff09;总结 2 #include1&#xff09;基本语法2&#xff09;头文件的作用3&#xff09;头文件的保护4&#xff09;示例5&#xff09;头文…

10 款最适合阅读和注释 PDF 文件的工具

简介 PDF 或便携式文档格式是 Adob​​e 在 20 世纪 90 年代创建的一种文件类型&#xff0c;作为轻松创建和分发文档的解决方案。如今&#xff0c;PDF 在世界各地的教育、企业、政府甚至互联网等行业中得到广泛应用。PDF 具有广泛的功能&#xff0c;包括多页文档、注释、超链接…

环保消毒餐具元宇宙

随着人们生活水平的提高&#xff0c;外卖和快餐已经成为了日常生活中不可或缺的一部分。然而&#xff0c;这些一次性餐具的使用也给环境带来了巨大的压力。为了解决这个问题&#xff0c;环保消毒餐具元宇宙应运而生。 环保消毒餐具元宇宙是一个基于区块链技术的虚拟世界&#…