package com;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import javax.xml.ws.Response;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.client.WebClient;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
public class WebClientTest {
public static void main(String[] args) {
//创建WebClient对象,并且设置请求基础路径
WebClient client = WebClient.create("http://localhost:8080");
//一个新用户
User user = new User();
user.setId(2L);
user.setUserName("李四");
user.setNote("好好");
user.setAge(13);
//新增用户
insertUser(client,user);
//获取用户
getUser(client, 2L);
User updUser = new User();
updUser.setId(2L);
updUser.setUserName("李四1");
updUser.setNote("好好1");
updUser.setAge(23);
//更新用户
updateUser(client,updUser);
//查询用户
findUsers(client, "李四1", "好好1");
//删除用户
delete(client, 2L);
}
private static void insertUser(WebClient client,User newUser) {
//注意:这只是定一个事件,并不会发送请求
Mono<UserVo> userMono =
//定义一个post请求
client.post()
//设置请求URI
.uri("/user")
//请求体位JSON数据流
.contentType(MediaType.APPLICATION_STREAM_JSON)
//请求体内容
.body(Mono.just(newUser),User.class)
//接受请求结果类型
.accept(MediaType.APPLICATION_STREAM_JSON)
//设置请求结果检索规则
.retrieve()
//将请求结果转为一个Mono封装的
.bodyToMono(UserVo.class);
//获取服务器发布的数据流,此时才会发送请求
UserVo userVo = userMono.block();
System.out.println(userVo.getId());
}
public static void getUser(WebClient client,Long id) {
Mono<UserVo> userMono =
//定义GET请求
client.get()
//定义请求URI和参数
.uri("/user/{id}",id)
//接受请求结果类型
.accept(MediaType.APPLICATION_STREAM_JSON)
//设置请求结果检索规则
.retrieve()
//将请求结果转为一个Mono封装的
.bodyToMono(UserVo.class);
//获取服务器发布的数据流,此时才会发送请求
UserVo userVo = userMono.block();
System.out.println(userVo.getId());
}
private static void updateUser(WebClient client,User updUser) {
Mono<UserVo> userMono =
//定义PUT请求
client.put().uri("/user")
//请求体位JSON数据流
.contentType(MediaType.APPLICATION_STREAM_JSON)
//请求体内容
.body(Mono.just(updUser),User.class)
//接受请求结果类型
.accept(MediaType.APPLICATION_STREAM_JSON)
//设置请求结果检索规则
.retrieve()
//将请求结果转为一个Mono封装的
.bodyToMono(UserVo.class);
//获取服务器发布的数据流,此时才会发送请求
UserVo userVo = userMono.block();
System.out.println(userVo.getId());
}
public static void findUsers(WebClient client,String userName,String note) {
//定义参数map
Map<String,Object> map = new HashMap<>();
map.put("userName", userName);
map.put("note", note);
Flux<UserVo> userFlux =
//定义get请求,使用Map传递多个参数
client.get().uri("/user/{userName}/{note}",map)
//接受请求结果类型
.accept(MediaType.APPLICATION_STREAM_JSON)
//设置请求结果检索规则
.retrieve()
//将请求结果转为一个Mono封装的
.bodyToFlux(UserVo.class);
//通过Iterator遍历结果数据流,执行后服务器才会响应
Iterator<UserVo> iterator = userFlux.toIterable().iterator();
while(iterator.hasNext()) {
UserVo userVo = iterator.next();
System.out.println(userVo.getId());
}
/* Flux<UserVo> userFlux =
//定义get请求,使用Map传递多个参数
client.get().uri("/user/{userName}/{note}",userName,note)
//接受请求结果类型
.accept(MediaType.APPLICATION_STREAM_JSON)
//设置请求结果检索规则
.retrieve()
//将请求结果转为一个Mono封装的
.bodyToFlux(UserVo.class);*/
}
private static void delete(WebClient client,Long id) {
Mono<Void> result = client.delete()
//设置请求URI
.uri("/user/{id}",id)
//接受请求结果类型
.accept(MediaType.APPLICATION_STREAM_JSON)
//设置请求结果检索规则
.retrieve()
//将请求结果转为一个Mono封装的
.bodyToMono(Void.class);
//获取服务器发布的数据流,此时才会发送请求
Void voidResult = result.block();
System.out.println(voidResult);
}
//客户端处理服务端的错误
public static void getUser2(WebClient client,Long id) {
Mono<UserVo> userMono =
//定义GET请求
client.get()
//定义请求URI和参数
.uri("/user/{id}",id)
//接受请求结果类型
.accept(MediaType.APPLICATION_STREAM_JSON)
//设置请求结果检索规则
.retrieve().onStatus(
//发生4开头或5开头的状态码,4开头是客户端错误,5开头是服务器错误
//第一个Lambda表达式,返回如果为true;则执行第二个Lambda表达式
status -> status.is4xxClientError()||status.is5xxServerError(),
//如果发生异常,则用第二个表达式返回作为结果
//第二个Lambda表达式
Response -> Mono.empty())
//将请求结果转为一个Mono封装的
.bodyToMono(UserVo.class);
//获取服务器发布的数据流,此时才会发送请求
UserVo userVo = userMono.block();
System.out.println(userVo.getId());
/**
* 以上代码解析:
* 这里采用onStatus方法,这个方法是监控服务器返回的方法。它的两个参数都采用了Lambda表达式的方式。第一个Lambda表达式的参数status是HttpStatus类型的
* ,它需要返回的是Boolean值,而代码给出的判断条件是是否为4开头(客户端错误)或者5开头(服务器错误)的服务响应码。第二个Lambda表达式的参数为ClientResponse
* 类型的,它在第一个Lambda表达式返回true时触发,这里是让结果转化为空(调用Mono的empty方法)。后面就使用userMono的block方法请求服务端,如果对应的用户
* 编号的用户不存在则服务器会抛出异常,这时请求就会出现HTTP服务状态码是4或者5开头的,这样就进行了错误处理的机制,返回为空。
*/
}
public static void getUser3(WebClient client,Long id) {
Mono<UserPojo> userMono =
//定义GET请求
client.get()
//定义请求URI和参数
.uri("/user/{id}",id)
//接受请求结果类型
.accept(MediaType.APPLICATION_STREAM_JSON)
//启用交换
.exchange()
//出现错误则返回空
.doOnError(ex -> Mono.empty())
//获取服务器发送过来的UserVo对象
.flatMap(response -> response.bodyToMono(UserVo.class))
//通过自定义方法转换为客户端的UserPojo
.map(user -> translate(user));
//获取客户端的UserPojo
UserPojo userPojo = userMono.block();
if(userPojo!=null) {
System.out.println("不为空");
}else {
System.out.println("为空");
}
/**
* 以上代码解析:
* 定义了translate方法,则是一个将服务器对象转换为客户端对象的方法。代码中不再使用retrieve方法,而是转用了exchange方法,它将允许自定义转换,会更加灵活。
* 为了处理错误,这里还定义了doOnError方法,一旦出现请求报错问题,则将返回空对象。在flatMap方法中,将对服务器的方法请求转换为Mono<UserVo>对象。
* 但这并不是客户端自定义的Mono<UserVo>对象,为了解决这个问题,还使用了map方法,然后通过translate方法将最后的结果转换为Mono<UserPojo>对象。
*/
}
public static UserPojo translate(UserVo vo) {
if(vo==null) {
return null;
}
UserPojo pojo = new UserPojo();//UserPojo该类是客户端那边的类
pojo.setId(vo.getId());
pojo.setNote(vo.getNote());
pojo.setAge(vo.getAge());
pojo.setUserName(vo.getUserName());
return pojo;
}
}