Spring WebFlux - 使用 WebClient 为 Mono 中列表的每个元素发送 HTTP 请求
Spring WebFlux - Send HTTP requests with WebClient for each element of a list inside a Mono
我们正在尝试将 MVC、resttemplate、阻塞、应用程序转换为 WebFlux 应用程序。
在“阻塞世界”中非常简单,获取请求负载中的列表,遍历它并向第三方发送 N 个 http 请求 rest API。
很重要是第三方restAPI,完全没法控制,不能要求他们实现一个版本拿单,得一个一个的做。
resttemplate 很简单,请问 WebFlux 的等效项是什么?
这有点挑战,因为它需要一个 Mono 和 returns 个 Mono。
一个小片段会很棒。
谢谢
@SpringBootApplication
@RestController
public class QuestionApplication {
public static void main(String[] args) {
SpringApplication.run(QuestionApplication.class, args);
}
@PostMapping("question")
MyResponse question(@RequestBody MyRequest myRequest) {
List<String> myStrings = myRequest.getListOfString();
List<Integer> myIds = iterateAndSendRequestOneByOneGetIdFromString(myStrings);
return new MyResponse(myIds);
}
private List<Integer> iterateAndSendRequestOneByOneGetIdFromString(List<String> myStrings) {
List<Integer> ids = new ArrayList<>();
for (String string : myStrings) {
Integer id = new RestTemplate().postForObject("http://external-service:8080/getOneIdFromOneString", string, Integer.class);
ids.add(id);
}
return ids;
}
// @PostMapping("how-to-do-the-same-with-WebFlux-WebClient-please?")
// Mono<MyResponse> question(@RequestBody Mono<MyRequest> myRequestMono) {
// return null;
// }
}
class MyResponse {
private List<Integer> myIds;
}
class MyRequest {
private List<String> strings;
}
方法是使用 Flux 中的flatMap
。
public Mono<MyResponse> getIdsFromStrings(MyRequest myRequest) {
WebClient client =
WebClient.builder().baseUrl("http://external-service:8080").build();
return Flux.fromIterable(myRequest.getStrings())
.flatMap(s -> client.post().uri("/getOneIdFromOneString").body(s, String.class).retrieve().bodyToMono(Integer.class))
.collectList()
.map(MyResponse::new);
}
.flatMap
是一个异步操作,将同时执行您的请求。您还可以选择使用 flatMap
的重载方法(请参阅文档)来设置并发限制。
我们正在尝试将 MVC、resttemplate、阻塞、应用程序转换为 WebFlux 应用程序。
在“阻塞世界”中非常简单,获取请求负载中的列表,遍历它并向第三方发送 N 个 http 请求 rest API。
很重要是第三方restAPI,完全没法控制,不能要求他们实现一个版本拿单,得一个一个的做。
resttemplate 很简单,请问 WebFlux 的等效项是什么? 这有点挑战,因为它需要一个 Mono 和 returns 个 Mono。 一个小片段会很棒。
谢谢
@SpringBootApplication
@RestController
public class QuestionApplication {
public static void main(String[] args) {
SpringApplication.run(QuestionApplication.class, args);
}
@PostMapping("question")
MyResponse question(@RequestBody MyRequest myRequest) {
List<String> myStrings = myRequest.getListOfString();
List<Integer> myIds = iterateAndSendRequestOneByOneGetIdFromString(myStrings);
return new MyResponse(myIds);
}
private List<Integer> iterateAndSendRequestOneByOneGetIdFromString(List<String> myStrings) {
List<Integer> ids = new ArrayList<>();
for (String string : myStrings) {
Integer id = new RestTemplate().postForObject("http://external-service:8080/getOneIdFromOneString", string, Integer.class);
ids.add(id);
}
return ids;
}
// @PostMapping("how-to-do-the-same-with-WebFlux-WebClient-please?")
// Mono<MyResponse> question(@RequestBody Mono<MyRequest> myRequestMono) {
// return null;
// }
}
class MyResponse {
private List<Integer> myIds;
}
class MyRequest {
private List<String> strings;
}
方法是使用 Flux 中的flatMap
。
public Mono<MyResponse> getIdsFromStrings(MyRequest myRequest) {
WebClient client =
WebClient.builder().baseUrl("http://external-service:8080").build();
return Flux.fromIterable(myRequest.getStrings())
.flatMap(s -> client.post().uri("/getOneIdFromOneString").body(s, String.class).retrieve().bodyToMono(Integer.class))
.collectList()
.map(MyResponse::new);
}
.flatMap
是一个异步操作,将同时执行您的请求。您还可以选择使用 flatMap
的重载方法(请参阅文档)来设置并发限制。