Spring boot3-WebClient远程调用非阻塞、响应式HTTP客户端
来吧,会用就行具体理论不讨论
1、首先pom.xml引入webflux依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
别问为什么因为是响应式.......都说不管理论了,继续
2、创建WebClientController控制器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import com.atguigu.boot3_07_http.service.WebClientService;
@RestController
public class WebClientController {
@Autowired
private WebClientService webClientService;// 等下创建真正干活的service类
/**
* 博主这里对接的是华为云的人脸API获取token的测试,用什么api测试都是大同小异的
* WebClient
* @param authWrapper 请求体消息,有华为云要的key,id,scecc,password,name啥啥的,根据自己的api要求来就行
* @return
*/
@PostMapping("/huawei")
public Mono<String> huawei(@RequestBody(required = false) AuthWrapper authWrapper) {
if (authWrapper == null) {
return Mono.just("请求体不能为空"); // 返回错误信息
}
return webClientService
.webClient("https://iam.cn-north-4.myhuaweicloud.com/v3/auth/tokens", authWrapper) //这里放接口地址和参数,当然authWrapper实际项目是从数据库拿的
.onErrorResume(e -> {
// 处理其他可能的异常
return Mono.just("发生错误:" + e.getMessage());
});
}
}
3、创建打工仔程序员WebClientService 类
import com.atguigu.boot3_07_http.entity.AuthWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Mono;
@Service
public class WebClientService {
public Mono<String> webClient(String url, AuthWrapper authWrapper) {
//远程调用
//1、创建WebClient
WebClient client = WebClient.create();
//2.编辑请求
return client.post()
.uri(url)
// .contentType(MediaType.APPLICATION_JSON) //和.header()一样的不用重复,推荐用.header自定义头部
.bodyValue(authWrapper) //请求体参数
.header("Content-Type", "application/json") //Content-Type字段,json格式,具体看api有要求请求头不
.retrieve()
//.bodyToMono(String.class) // 获取响应体的JSON数据并转换为String类型的Mono对象
.toBodilessEntity() // 应为博主测试的api返回的是响应头,所有不关注响应体
.map(response -> {
String token = response.getHeaders().getFirst("X-Subject-Token");//获取字段X-Subject-Token响应头消息
if (token == null) {
// 不抛出异常,而是返回错误信息
return "错误:未获取到华为云Token";
}
return token;
//或者if去掉,用Objects.requireNonNullElse() //对象不为空输出:参数1,为空输出:参数2
// return Objects.requireNonNullElse(token, "错误:未获取到华为云Token");
});
}
}
最后看下返回结果,华为云返回的token
好啦,WebClient远程调用非阻塞、响应式HTTP客户端
最后大家有没有觉得,比RestTemplate传统的方便很多,但是没有实现高可用,有新的请求还有要搞一堆,我们使用 Http Interface: 声明式编程(官方推荐,也是很多大型项目的用法),并且创建工厂接口,这样只用写一次,以后需要的不用api可用直接调用,我也同时更新出来了