java - Project Reactor如何并行调用两个或多个web服务或REST并加入答案

标签 java spring spring-boot project-reactor

您好,我想知道如何在 pararelo 中调用两个或多个 Web 服务或 Rest 服务,并编写调用响应。

我在网上找到了一些使用其他技术的例子,但我无法让它与 react 堆一起工作

// start task A asynchronously
CompletableFuture<ResponseA> futureA = asyncServiceA.someMethod(someParam);
// start task B asynchronously
CompletableFuture<ResponseB> futureB = asyncServiceB.someMethod(someParam);

CompletableFuture<String> combinedFuture = futureA
        .thenCombine(futureB, (a, b) -> a.toString() + b.toString());

// wait till both A and B complete
String finalValue = combinedFuture.join();

////////////////////////////////////////////////////////////////////////////

static void Run()
{
    //Follow steps at this link for addding a reference to the necessary .NET library:
    //http://stackoverflow.com/questions/9611316/system-net-http-missing-from-    
    //namespace-using-net-4-5

    //Create an HTTP Client
    var client = new HttpClient();

    //Call first service
    var task1 = client.GetAsync("http://www.cnn.com");

    //Call second service
    var task2 = client.GetAsync("http://www.google.com");

    //Create list of all returned async tasks
    var allTasks = new List<Task<HttpResponseMessage>> { task1, task2 };

    //Wait for all calls to return before proceeding
    Task.WaitAll(allTasks.ToArray());

}

最佳答案

假设您需要访问 2 个服务,所以您需要 2 个基础 WebClient (每个都配置了正确的基本 URL 和身份验证方案):

@Bean
public WebClient serviceAClient(String authToken) {
    return WebClient.builder()
            .baseUrl("http://serviceA.com/api/v2/")
            .defaultHeader(HttpHeaders.AUTHORIZATION, "Basic " + authToken)
            .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .build();
}

@Bean
public WebClient serviceBClient(String authToken): WebClient {
    return WebClient.builder()
            .baseUrl("https://api.serviceB.com/")
            .defaultHeader(HttpHeaders.AUTHORIZATION, "token " + authToken)
            .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .build();
}

从那里开始,假设您将这 2 个 Web 客户端注入(inject)到您的 Controller 中(作为 合格 bean)。下面是使用 Reactor 对两者进行联合调用的代码:

Mono<ResponseA> respA = webclientA.get()
                                 .uri("/sub/path/" + foo)
                                 .retrieve()
                                 .bodyToMono(ResponseA.class);
Mono<ResponseB> respB = webclientB.get()
                                 .uri("/path/for/b")
                                 .retrieve()
                                 .bodyToMono(ResponseB.class);
Mono<String> join = respA.zipWith(respB, (a, b) -> a.toString + b.toString);
return join;

请注意,zip 函数可以从 2 个响应中生成更有意义的内容,例如业务对象。结果 Mono<String>仅当有内容订阅时触发 2 个请求(在 Spring WebFlux 的情况下,如果您从 Controller 方法返回它,框架将执行此操作)。

关于java - Project Reactor如何并行调用两个或多个web服务或REST并加入答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48762680/

相关文章:

java - 来自 xml 的 Spring Context 类加载器

java - 我每隔几天就会收到服务器错误

spring - 将 RowMapper 类定义为 spring bean 可以吗?

java - Spring Boot - Rest Controller 在使用 Lombok 时返回空对象

java - JPA 持久性和 Hibernate javassist 对象

java - 无法自动连接[错误 : No matching bean of type]

java - Xpath - 如何获取元素之间包含的数据,而不是元素本身

java - 如何使用spring aop记录方法链

java - Spring 启动| LifecycleProcessor 未初始化 - 在调用生命周期方法之前调用 'refresh' 异常

spring - 如何定义重试次数不应该尝试使用 hystrix