当前位置:网站首页>新版负载均衡WebClient CRUD

新版负载均衡WebClient CRUD

2022-06-22 14:16:00 InfoQ

Webclient 使用场景

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

Webclient 的RestFul 请求

一、RESTful风格与HTTP method

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



下面我们就来讲下这些资源场景的使用方式。
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(&quot;username&quot;, &quot;damoin&quot;);
 map.add(&quot;UID&quot;, &quot;11024319902323&quot;);

 Mono<String> mono = webClientBuilder.build().post()
 .uri(&quot;http://rest-service-service/add&quot;)
 .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(&quot;dwdwdww&quot;);
 user.setPhone(&quot;32323232&quot;);
 Mono<String> mono = webClientBuilder.build()
 .post()
 .uri(&quot;http://rest-service-service/add&quot;)
 .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 = &quot;{\&quot;realName\&quot;: \&quot;damon\&quot;,\&quot;phone\&quot;: \&quot;32323232\&quot;}&quot;;
 Mono<String> mono = webClientBuilder.build().post()
 .uri(&quot;http://rest-service-service/add&quot;)
 .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(&quot;http://rest-service-service/1&quot;);
}
PUT
修改一个已经存在的资源,使用webClient的put()方法。该方法会向URL代表的资源发送一个HTTP PUT方法请求:

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

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

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

这里以传json数据的格式来进行发送修改,修改完成后返回修改结果信息。
GET
新增完数据后,我们来查看数据对象,如果是一个对象数据的话,可以使用 Mono:

@GetMapping(value = &quot;/getClientResByWebClient2&quot;, produces = MediaType.TEXT_EVENT_STREAM_VALUE)
 public Mono<String> getClientResByWebClient2() throws Exception {
 Mono<String> resp = webClientBuilder.build()
 .get()
 .uri(&quot;http://diff-ns-service-service/all/getService&quot;)
 .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(&quot;http://diff-ns-service-service/all&quot;)
 .retrieve()
 .bodyToFlux(SysUser.class);
 List<SysUser> li = flux.collectList().block();
 assert li != null;
 System.out.println(&quot;li集合元素数量:&quot; + li.size());
}

原网站

版权声明
本文为[InfoQ]所创,转载请带上原文链接,感谢
https://xie.infoq.cn/article/3686ea7c884f58d27e0266ed6