这是我参与11月更文挑战的第2天,活动详情查看:2021最后一次更文挑战。 上次学习了springboot webFlux的简单开发工作,今天继续学习webFlux。在实际的开发工作中,我们有时需要返回单个数据,有时需要返回集合数据和MAP数据。而在webFlux中所有的返回都是通过Flux或Mono包装返回。 一、数据响应 1、返回单个对象 /mono
@GetMapping("mono")
public Mono<Object> mono() {
return Mono.create(monoSink -> {
log.info("创建 Mono");
monoSink.success("hello webflux");
})
.doOnSubscribe(subscription -> { //当订阅者去订阅发布者的时候,该方法会调用
log.info("subscription={}", subscription);
}).doOnNext(o -> { //当订阅者收到数据时,改方法会调用
log.info("o={}", o);
});
}
复制代码
2、返回List数据 /userList
//返回List集合
@GetMapping("userList")
public Flux<User> userList() {
List<User> list = new ArrayList<>();
IntStream.range(1,10).forEach(i->{
User user = new User("No:1000"+i,"jack",
"1899976965",
"[email protected]","南路木",new Date());
list.add(user);
});
return Flux.fromIterable(list);
}
复制代码
3、返回Map数据 /userMap
@GetMapping("userMap")
public Flux<Map.Entry<String, User>> userMap() {
Map<String, User> map = new HashMap<>();
IntStream.range(1,10).forEach(i->{
User user = new User("No:1000"+i,"jack",
"1899976965",
"[email protected]","南路木",new Date());
map.put(user.getId(),user);
});
return Flux.fromIterable(map.entrySet());
}
复制代码
集合数据通过Flux.fromIterable的方法处理。
二、WebClient的使用 开发响应式HTTP请求就需要用到webClient。 1、创建WebClient对象并指定baseUrl; 2、指定HTTP请求方式GET/POST; 3、异步地获取response信息; 4、将response body解析为字符串。
@RequestMapping("test1")
public void clientTest(){
WebClient webClient = WebClient.create("http://localhost:8080"); // 1
Mono<String> resp = webClient
.get().uri("/flux/hello") // 2
.retrieve() // 3
.bodyToMono(String.class); // 4
resp.subscribe(System.out::println); // 5
try {
TimeUnit.SECONDS.sleep(1); // 6
} catch (InterruptedException e) {
e.printStackTrace();
}
}
复制代码
这样/test1方法就能访问http://localhost:8080/flux/hello的接口数据。
@RequestMapping("test2")
public Flux<User> clientTest2() throws InterruptedException {
WebClient webClient = WebClient.builder().baseUrl("http://localhost:8080").build(); // 1
return webClient
.get().uri("/flux/user")
.accept(MediaType.APPLICATION_STREAM_JSON) // 2
.exchange() // 3
.flatMapMany(response -> response.bodyToFlux(User.class)) // 4
.doOnNext(System.out::println) // 5
.blockLast(); // 6
;
}
复制代码
1、这次使用WebClientBuilder来构建WebClient对象; 2、配置请求Header:Content-Type: application/stream+json; 3、获取response信息,返回值为ClientResponse,retrive()可以看做是exchange()方法的"快捷版"; 4、使用flatMap来将ClientResponse映射为Flux; 5、只读地peek每个元素,然后打印出来,它并不是subscribe,所以不会触发流; 6、blockLast方法,顾名思义,在收到最后一个元素前会阻塞,响应式业务场景中慎用。
三、浏览器定时响应的例子
//每秒会给浏览器推送数据
@GetMapping(value = "/interval", produces = MediaType.TEXT_EVENT_STREAM_VALUE)
private Flux<String> flux() {
Flux<String> result = Flux
.fromStream(IntStream.range(1, 13).mapToObj(i -> {
log.info("i="+i);
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
return "this data is " + i;
}));
return result;
复制代码
下一节继续学习WebFlux的WebSocket的异步处理及连接spring Data的使用。