简体   繁体   English

Spring WebFlux 和 WebClient 调用不起作用

[英]Spring WebFlux and WebClient Call not working

I'm a newbie in reactive programming, I have the following rest resource that calls a service that use WebClient to call an existing Rest API:我是反应式编程的新手,我有以下 rest 资源调用使用 WebClient 调用现有 Rest API 的服务:

   @PostMapping
    public Mono<String> createUser(@RequestBody UserResourceDTO userResourceDto) {
        return userService.createUser(userResourceDto);
    }

in my service I have the following methode which works fine:在我的服务中,我有以下方法可以正常工作:

// Working method
   public Mono<String> createUser(UserResourceDTO userResourceDTO){
        return  httpCall(userResourceDTO);
  }

when I use this method the HTTP call is triggered and I see it in my log, but since I don't want to return the value from this method I tried the following method:当我使用此方法时,将触发 HTTP 调用并在我的日志中看到它,但由于我不想从此方法返回值,因此我尝试了以下方法:

// Not Working method
    public Mono<String> createUser(UserResourceDTO userResourceDTO){
        Mono<String> rs = httpCall(userResourceDTO);
       return  Mono.just("just a value");
       
        // i plan to trigger another call to the DB this is why i don't want to return the result from httpCall
       // return userRepository.createUser(userResourceDTO);

}

this method is not working and the HTTP request is not triggered ( i don't see it in the console like the first method), can anyone explain to me why the second method is not triggering the WebClient call and why I'm obliged to return the result from mhttpCall(userResourceDTO);此方法不起作用并且未触发 HTTP 请求(我没有像第一种方法那样在控制台中看到它),任何人都可以向我解释为什么第二种方法没有触发 WebClient 调用以及为什么我有义务从mhttpCall(userResourceDTO);

this is httpCall code:这是 httpCall 代码:

public Mono<String> httpCall(UserResourceDTO userResourceDTO) {

    WebClient webClient = WebClient.create();

    KeyCloakUser keyCloakUser = new KeyCloakUser();
    // setting values...
  
    return webClient.post()
            .uri(new URI("myurl"))
            .header("Authorization", "Bearer "+toremove)                
            .header(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
            .body(Mono.just(keyCloakUser), KeyCloakUser.class)
            .retrieve()
            .bodyToMono(String.class);
}

This is one of the common mistakes after switching to reactive programming.这是切换到响应式编程后的常见错误之一。 In reactive nothing happens until you subscribe.在你订阅之前,反应式不会发生任何事情。 You need to chain async/sync functions using reactive operators like flatMap , map , etc.您需要使用响应式运算符(如flatMapmap等)链接异步/同步函数。

Good starting point to understand the concept is Flight of the Flux 1 - Assembly vs Subscription .理解该概念的良好起点是Flight of the Flux 1 - Assembly vs Subscription

Incorrect不正确

public Mono<String> createUser(UserResourceDTO userResourceDTO){
     Mono<String> rs = httpCall(userResourceDTO);
     return  Mono.just("just a value");
}

httpCall(userResourceDTO) will not be executed as a part of the reactive flow. httpCall(userResourceDTO)不会作为反应流的一部分执行。

Correct正确的

public Mono<String> createUser(UserResourceDTO userResourceDTO){
     return httpCall(userResourceDTO)
        .then(Mono.just("just a value"));
}

to continue with another async call继续另一个异步调用

public Mono<String> createUser(UserResourceDTO userResourceDTO){
     return httpCall(userResourceDTO)
        .then(userRepository.createUser(userResourceDTO));
}

or, in case you need result of the HTTP call或者,如果您需要 HTTP 调用的结果

public Mono<String> createUser(UserResourceDTO userResourceDTO){
     return httpCall(userResourceDTO)
        .flatMap(res -> userRepository.createUser(userResourceDTO));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM