使用WebClient进行Http远程调用
文章目录
- WebClient 一旦创建,就是不可修改的,如果需要设置默认值,可以借助 mutate 继承当前webclient的属性,再进行扩展
- subscribe方式获取的是webFlux接口返回的数据 ans.subscribe(s -> System.out.println("create return: " + s));
- 传统接口使用block阻塞获取内容
- GET请求 webClient.get().uri(xxx).retrieve().bodyToMono/bodyToFlux,分别获取Mono和Flux数据
- bodyToMono用于获取0个或1个元素,而bodyToFlux对象获取1个或多个元素
引入webFlux依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
1.WebClient对象创建
/**
* WebClient 创建,
* 1.create创建WebClient实例
* 2.build创建WebClient实例(可以设置请求头等参数)
* 3.mutate 方式 在一个已经存在的WebClient基础上,再创建一个满足自定义需求的WebClient
* 发起get请求,并将返回的数据格式转换为String;因为是异步请求,所以返回的是Mono包装的对象
*/
WebClient webClient= WebClient.create();
Mono<String> ans = webClient.get()
.uri("http://127.0.0.1:12000/api/v1/service/wechat/xxx").retrieve().bodyToMono(String.class);
System.out.println("create return: " + ans.block());
webClient= WebClient.create();
Flux<String> an1 = webClient.get().uri("http://127.0.0.1:12000/api/v1/service/xxx")
.retrieve().bodyToFlux(String.class);
an1.toStream().forEach(System.out::println);
webClient = WebClient.builder().defaultHeader("User-Agent", "WebClient Agent").build();
ans = webClient.get().uri("http://127.0.0.1:12000/api/v1/service/wechat/xxx").retrieve().bodyToMono(String.class);
System.out.println("builder return: " + ans.block());
webClient = webClient.mutate().defaultCookie("cookie", "aaa").build();
ans = webClient.get().uri("http://127.0.0.1:12000/api/v1/service/wechat/xxx").retrieve().bodyToMono(String.class);
System.out.println("mutate return: " + ans.block());
2.WebClient对象抽取config配置
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.client.WebClient;
@Configuration
public class WebClientConfig {
@Bean
public WebClient webClient() {
return WebClient.builder()
//默认基础地址,配置后后续请求可以不加
.baseUrl("http://127.0.0.1:12000")
.defaultHeader("Content-Type", "application/json")
.defaultHeader("Accept", "application/json")
.build();
}
}
@Autowired
private WebClient webClient;
3.Get请求url参数设置
//url参数
ans = webClient.get()
.uri("http://127.0.0.1:12000/api/v1/wechat/xxx/info?year={a}",1).retrieve().bodyToMono(String.class);
System.out.println("create return: " + ans.block());
//map映射url参数
Map<String, Object> uriVariables = new HashMap<>();
uriVariables.put("a", 1);
uriVariables.put("b", "测试");
ans = webClient.get()
.uri("http://127.0.0.1:12000/api/v1/service/wechat/xxx?action=arrival&isYear={a}&keyword={b}",uriVariables)
.retrieve().bodyToMono(String.class);
System.out.println("create return: " + ans.block());
4.获取ResponseEntity对象
//获取 ResponseEntity
Mono<ResponseEntity<String>> response = webClient.get().uri("http://127.0.0.1:12000/api/v1/service/wechat/xxx")
.exchange().flatMap(r -> r.toEntity(String.class));
ResponseEntity<String> entity = Objects.requireNonNull(response.block());
System.out.println(" headers: " + entity.getHeaders() + " body: " + entity.getBody());
5.Post请求
//表单参数
webClient = WebClient.create("http://127.0.0.1:12000");
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
formData.add("name", "张三");
formData.add("age", "18");
ans = webClient.post().uri("/post")
.bodyValue(formData).retrieve().bodyToMono(String.class);
System.out.println("post formData ans " + ans.block());
// json参数
UserObj userObj = new UserObj("张三",18);
ans = webClient.post().uri("/body").contentType(MediaType.APPLICATION_JSON).bodyValue(userObj).retrieve()
.bodyToMono(String.class);
System.out.println("post formData ans " + ans.block());
测试示例代码
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* WebClient 一旦创建,就是不可修改的,如果需要设置默认值,可以借助 mutate 继承当前webclient的属性,再进行扩展
* subscribe方式获取的是webFlux接口返回的数据 ans.subscribe(s -> System.out.println("create return: " + s));
* 传统接口使用block阻塞获取内容
* GET请求 webClient.get().uri(xxx).retrieve().bodyToMono/bodyToFlux,分别获取Mono和Flux数据
*/
public class WebClientTest {
public static void main(String[] args) {
/**
* WebClient 创建,
* 1.create创建WebClient实例
* 2.build创建WebClient实例(可以设置请求头等参数)
* 3.mutate 方式 在一个已经存在的WebClient基础上,再创建一个满足自定义需求的WebClient
* 发起get请求,并将返回的数据格式转换为String;因为是异步请求,所以返回的是Mono包装的对象
*/
WebClient webClient= WebClient.create();
Mono<String> ans = webClient.get().uri("http://127.0.0.1:12000/api/v1/service/wechat/xxx").retrieve().bodyToMono(String.class);
System.out.println("create return: " + ans.block());
webClient= WebClient.create();
Flux<String> an1 = webClient.get().uri("http://127.0.0.1:12000/api/v1/service/xxx")
.retrieve().bodyToFlux(String.class);
an1.toStream().forEach(System.out::println);
webClient = WebClient.builder().defaultHeader("User-Agent", "WebClient Agent").build();
ans = webClient.get().uri("http://127.0.0.1:12000/api/v1/service/wechat/xxx").retrieve().bodyToMono(String.class);
System.out.println("builderCreate with header return: " + ans.block());
webClient = webClient.mutate().defaultCookie("ck", "--web--client--ck--").build();
ans = webClient.get().uri("http://127.0.0.1:12000/api/v1/service/wechat/xxx").retrieve().bodyToMono(String.class);
System.out.println("webClient#mutate with cookie return: " + ans.block());
/**
* url参数设置
* 1.url可变参数
* 2.map映射url参数
*/
//url可变参数
ans = webClient.get()
.uri("http://127.0.0.1:12000/api/v1/wechat/xxx/info?year={a}",1).retrieve().bodyToMono(String.class);
System.out.println("create return: " + ans.block());
//map映射url参数
Map<String, Object> uriVariables = new HashMap<>();
uriVariables.put("a", 1);
uriVariables.put("b", "测试");
ans = webClient.get()
.uri("http://127.0.0.1:12000/api/v1/service/wechat/xxx?action=arrival&isYear={a}&keyword={b}",uriVariables)
.retrieve().bodyToMono(String.class);
System.out.println("create return: " + ans.block());
//获取 ResponseEntity
Mono<ResponseEntity<String>> response = webClient.get().uri("http://127.0.0.1:12000/api/v1/service/wechat/xxx")
.exchange().flatMap(r -> r.toEntity(String.class));
ResponseEntity<String> entity = Objects.requireNonNull(response.block());
System.out.println("res headers: " + entity.getHeaders() + " body: " + entity.getBody());
/**
* post请求
* 1.表单
* 2.json数据
*/
//表单参数
webClient = WebClient.create("http://127.0.0.1:12000");
MultiValueMap<String, String> formData = new LinkedMultiValueMap<>();
formData.add("name", "张三");
formData.add("age", "18");
//默认的ContentType就是"application/x-www-form-urlencoded",所以下面这个contentType是可以不显示设置的
ans = webClient.post().uri("/post")
// .contentType(MediaType.APPLICATION_FORM_URLENCODED)
.bodyValue(formData).retrieve().bodyToMono(String.class);
System.out.println("post formData ans " + ans.block());
// json参数
UserObj userObj = new UserObj("张三",18);
ans = webClient.post().uri("/body").contentType(MediaType.APPLICATION_JSON).bodyValue(userObj).retrieve()
.bodyToMono(String.class);
System.out.println("post formData ans " + ans.block());
}
}
参考原文:https://blog.csdn.net/cxyxysam/article/details/135425646