WebClient 增删改查一文搞定

简介: 随着Spring官方对于响应式编程的大力推广,WebClient等响应式编程越来越成为主要趋势,本文主要讲解Webclient的增删改查。

Webclient 使用场景

前面介绍了 什么是阻塞、非阻塞,以及对应的客户端库,非阻塞在高并发内存不足的情况下,还是一个不错的选择,当被访问者的服务响应很慢、或者自己在请求对方时,并不是很想知道对方返回的结果,都可以使用 Webclient 来进行非阻塞式请求。下面紧接着讲非阻塞客户端库 Webclient如何实现增删改查。

Webclient 的RestFul 请求

一、RESTful风格与HTTP method

熟悉RESTful风格的朋友,应该了解RESTful风格API使用HTTP method表达对资源的操作。

常用HTTP方法 RESTful风格语义(操作)
POST 新增、提交数据
DELETE 删除数据
PUT 更新、修改数据
GET 查询、获取数据

下面我们就来讲下这些资源场景的使用方式。

POST

POST等常见使用如下方法:

  • block()阻塞获取响应结果的方法
  • subscribe()非阻塞异步结果订阅方法
  • retrieve()获取HTTP响应体,exchange()除了获取HTTP响应体,还可以获取HTTP 状态码、headers、cookies等HTTP报文信息。
  • 使用Mono接收单个对象的响应结果,使用Flux接收集合类对象的响应结果。
  • 占位符语法传参方式

模拟表单提交数据

public void testFormSubmit() {

   MultiValueMap<String, String> map = new LinkedMultiValueMap<>();
   map.add("username", "damoin");
   map.add("UID", "11024319902323");

   Mono<String> mono = webClientBuilder.build().post()
                   .uri("http://rest-service-service/add")
                   .contentType(MediaType.APPLICATION_FORM_URLENCODED)
                   .body(BodyInserters.fromFormData(map))
                   .retrieve()
                   .bodyToMono(String.class);

   System.out.println(mono.block());
}

如上所示,在提交表单的时候,需要说明表单数据类型,以及表单的具体数据,我们知道:常见的表单数据都是以map形式存在,在请求后要想获取响应返回,可以使用retrieve函数,同时可以借助Mono来对返回结果进行类型转换,如果是单个对象使用Mono,如果是集合流,可以使用Flux。同时,如果想要阻塞拿到返回结果的信息,可以通过block函数来处理。

传输对象以JSON数据形式发送

public void testPostJson() {
   SysUser user = new SysUser();
   user.setRealName("dwdwdww");
   user.setPhone("32323232");
   Mono<String> mono = webClientBuilder.build()
                   .post()
                   .uri("http://rest-service-service/add")
                   .contentType(MediaType.APPLICATION_JSON)
                   .bodyValue(user)
                   .retrieve()
                   .bodyToMono(String.class);

   System.out.println(mono.block());
   }

这里将传输的数据以Json格式来进行发送给对方,同样需要注明数据类型MediaType.APPLICATION_JSON,其它的函数都是跟上面一样。

模拟向服务端发送JSON字符串数据

如果有时候对方需要的不是一个JSON对象,可能是需要一个JSON字符串,那怎么办呢?

public void testPostJsonStr() {
   String jsonStr = "{\"realName\": \"damon\",\"phone\": \"32323232\"}";
   Mono<String> mono = webClientBuilder.build().post()
                   .uri("http://rest-service-service/add")
                   .contentType(MediaType.APPLICATION_JSON)
                   .body(BodyInserters.fromValue(jsonStr))
                   .retrieve()
                   .bodyToMono(String.class);

   // 输出结果
   System.out.println(mono.block());
}

此时,数据类型同样还是 MediaType.APPLICATION_JSON,但传输的是JSON串。

DELETE

使用 DELETE方法去删除资源,删除一个已经存在的资源,使用webClient的delete()方法。该方法会向URL代表的资源发送一个HTTP DELETE方法请求:

public void testDelete()  {
 webClientBuilder.build()
 .delete()
 .uri("http://rest-service-service/1");
}

PUT

修改一个已经存在的资源,使用webClient的put()方法。该方法会向URL代表的资源发送一个HTTP PUT方法请求:

public void testPut() {
       SysUser user = new SysUser();
       user.setRealName("dwdwdww");
       user.setPhone("32323232");

       Mono<String> mono = webClientBuilder.build()
                       .put()
                       .uri("http://rest-service-service/1")
                       .contentType(MediaType.APPLICATION_JSON)
                       .bodyValue(user).retrieve().bodyToMono(String.class);

       System.out.println(mono.block());
}

这里以传json数据的格式来进行发送修改,修改完成后返回修改结果信息。

GET

新增完数据后,我们来查看数据对象,如果是一个对象数据的话,可以使用 Mono:

@GetMapping(value = "/getClientResByWebClient2", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
   public Mono<String> getClientResByWebClient2() throws Exception {
            Mono<String> resp = webClientBuilder.build()
            .get()
            .uri("http://diff-ns-service-service/all/getService")
            .retrieve().bodyToMono(String.class);
            //.exchange().flatMap(clientResp -> clientResp.bodyToMono(String.class));

           resp.subscribe(body -> System.out.println(body));
           return resp;
   }

如果是多个对象,那就是集合集,此时需要用Flux来获取:

public void testFlux() {
   Flux<SysUser> flux = webClientBuilder.build()
             .get()
             .uri("http://diff-ns-service-service/all")
             .retrieve()
             .bodyToFlux(SysUser.class);
     List<SysUser> li = flux.collectList().block();
     assert li != null;
     System.out.println("li集合元素数量:" + li.size());
}

相关文章
|
8月前
|
SQL 数据库 开发者
Python中使用Flask-SQLAlchemy对数据库的增删改查简明示例
这样我们就对Flask-SQLAlchemy进行了一次简明扼要的旅程,阐述了如何定义模型,如何创建表,以及如何进行基本的数据库操作。希望你在阅读后能对Flask-SQLAlchemy有更深入的理解,这将为你在Python世界中从事数据库相关工作提供极大的便利。
744 77
|
8月前
|
XML 数据库 Android开发
Android数据库的使用(增删改查)
本文介绍了一个简单的数据库操作Demo,包含创建数据库、增删改查功能。通过5个按钮分别实现创建数据库、插入数据、删除数据、更新数据和查询数据的操作。代码结构清晰,适合初学者学习Android SQLite数据库基础操作。
261 5
|
8月前
|
数据库 Android开发 开发者
Android常用的room增删改查语句(外部数据库)
本文分享了将一个原生数据库驱动的单词APP重构为使用Room库的过程及遇到的问题,重点解决了Room中增删改查的常用语句实现。文章通过具体示例(以“forget”表为例),详细展示了如何定义实体类、Dao接口、Database类以及Repository和ViewModel的设计与实现。同时,提供了插入、删除、更新和查询数据的代码示例,包括模糊查询、分页加载等功能。此外,针对外部数据库导入问题,作者建议可通过公众号“计蒙不吃鱼”获取更多支持。此内容适合有一定Room基础的开发者深入学习。
265 0
Android常用的room增删改查语句(外部数据库)
|
11月前
|
关系型数据库 MySQL 数据库连接
Unity连接Mysql数据库 增 删 改 查
在 Unity 中连接 MySQL 数据库,需使用 MySQL Connector/NET 作为数据库连接驱动,通过提供服务器地址、端口、用户名和密码等信息建立 TCP/IP 连接。代码示例展示了如何创建连接对象并执行增删改查操作,确保数据交互的实现。测试代码中,通过 `MySqlConnection` 类连接数据库,并使用 `MySqlCommand` 执行 SQL 语句,实现数据的查询、插入、删除和更新功能。
|
SQL 关系型数据库 API
HarmonyOs开发:关系型数据库封装之增删改查
每个方法都预留了多种调用方式,比如使用callback异步回调或者使用Promise异步回调,亦或者同步执行,大家在使用的过程中,可以根据自身业务需要进行选择性调用,也分别暴露了成功和失败的方法,可以针对性的判断在执行的过程中是否执行成功。
476 13
|
SQL 关系型数据库 MySQL
学成在线笔记+踩坑(3)——【内容模块】课程分类查询、课程增改删、课程计划增删改查,统一异常处理+JSR303校验
课程分类查询、课程新增、统一异常处理、统一封装结果类、JSR303校验、修改课程、查询课程计划、新增/修改课程计划
学成在线笔记+踩坑(3)——【内容模块】课程分类查询、课程增改删、课程计划增删改查,统一异常处理+JSR303校验
|
存储 NoSQL API
使用Py2neo进行Neo4j图数据库的增删改查操作
使用Py2neo进行Neo4j图数据库的增删改查操作
537 5
|
数据可视化 API PHP
低代码开发工具-学生管理系统-老师管理增删改查实现
低代码开发工具-学生管理系统-老师管理增删改查实现
221 5
|
前端开发 Java 数据库连接
javamvc配置,增删改查,文件上传下载。
【10月更文挑战第4天】javamvc配置,增删改查,文件上传下载。
136 1
|
SQL 关系型数据库 MySQL
ThinkPHP6 连接使用数据库,增删改查,find,select,save,insert,insertAll,insertGetId,delete,update方法的用法
本文介绍了在ThinkPHP6框架中如何连接和使用数据库进行增删改查操作。内容包括配置数据库连接信息、使用Db类进行原生MySQL查询、find方法查询单个数据、select方法查询数据集、save方法添加数据、insertAll方法批量添加数据、insertGetId方法添加数据并返回自增主键、delete方法删除数据和update方法更新数据。此外,还说明了如何通过数据库配置文件进行数据库连接信息的配置,并强调了在使用Db类时需要先将其引入。
ThinkPHP6 连接使用数据库,增删改查,find,select,save,insert,insertAll,insertGetId,delete,update方法的用法