【问题标题】:Spring WebFlux - Send HTTP requests with WebClient for each element of a list inside a MonoSpring WebFlux - 使用 WebClient 为 Mono 中列表的每个元素发送 HTTP 请求
【发布时间】:2020-08-24 21:05:55
【问题描述】:

我们正在尝试将 MVC、resttemplate、blocking、应用程序转换为 WebFlux 应用程序。

在“阻塞世界”中非常简单,在请求负载中获取一个列表,遍历它并将 N 个 http 请求发送到第三方 rest API。

很重要的是第三方rest API,根本无法控制,也不能要求他们实现一个取列表的版本,必须一个一个。

resttemplate 很简单,请问 WebFlux 的等价物是什么? 这有点挑战性,因为它需要一个 Mono 并返回一个 Mono。 一个小的 sn-p 会很棒。

谢谢

@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;
}

【问题讨论】:

  • 你试过什么?

标签: java spring spring-webflux spring-webclient


【解决方案1】:

要走的路是使用来自 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 的重载方法设置并发限制(请参阅文档)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-01-30
    • 2019-06-04
    • 1970-01-01
    • 2021-10-26
    • 1970-01-01
    • 2023-03-08
    • 2019-09-19
    • 2022-01-18
    相关资源
    最近更新 更多