简体   繁体   中英

Java Spring Boot Webflux - Mono response when there is no http body, but just http status

Small question regarding Spring Boot Webflux 2.5.0 and how to deal with a http response without body.

By "without body" I mean:

For instance, a web application I consume the rest API and have no control returns:

HTTP status code 200
HTTP body {"foo": "bar"}

With Spring Webflux, we can easily write something like:

public Mono<FooBar> sendRequest(SomeRequest someRequest) {
        return webClient.mutate()
                        .baseUrl("https://third-party-rest-api.com:443")
                        .build()
                        .post()
                        .uri(/someroute)
                        .body(BodyInserters.fromValue(someRequest))
                        .retrieve().bodyToMono(FooBar.class);
}

public class FooBar {
    
    private String foo;

    //getter setters

}

In order to get the POJO corresponding to the http body.

Now, another third party API I am consuming only return HTTP 200 as status response. I would like to emphasize, there is no HTTP body. It is not the empty JSON {}.

Hence, I am a bit lost, and do not know what to put here. Especially with the goal of avoiding the mono empty.

public Mono<WhatToPutHerePlease> sendRequest(SomeRequest someRequest) {
        return webClient.mutate()
                        .baseUrl("https://third-party-rest-api.com:443")
                        .build()
                        .post()
                        .uri(/someroute-with-no-http-body-response)
                        .body(BodyInserters.fromValue(someRequest))
                        .retrieve()
                        .bodyToMono(WhatToPutHerePlease.class);
}

Any help please?

Thank you

Hence, I am a bit lost, and do not know what to put here.

The response is empty, so there's nothing for your webclient to parse and return a value. The resulting Mono is thus always going to be empty, whatever generic type you use.

We have a special type that essentially says "this will always be empty" - Void (note the capital V .) So if you want to return an empty Mono, keeping the rest of the code the same, that's the type you should use.

Alternatively, if you don't want to return an empty publisher, then you might consider using .retrieve().toBodiLessEntity() instead of .retrieve().bodyToMono() - this will return a Mono<ResponseEntity<Void>> . The resulting body will obviously still be empty, but the response entity returned will enable you to extract information such as the response code & header information, should that be useful.

toBodylessEntity() seems to suit your needs:

It returns a Mono<ResponseBody<Void>> .

With a (void rest) controller like:

@RestController 
@SpringBootApplication
public class Demo {
  public static void main(String[] args) {
    SpringApplication.run(Demo.class, args);
    // ... 
  }
  @GetMapping("/")
  public void empty() {

  }
}

and a:

public class ReactiveClient {

  Mono<ResponseEntity<Void>> mono = WebClient.create("http://localhost:8080")
    .get()
    .retrieve()
    .toBodilessEntity();

  // blocking/synchronous
  public ResponseEntity<Void> get() {
    return mono.block();
  }
}

We can:

ReactiveClient reactiveClient = new ReactiveClient();
System.out.println(reactiveClient.get()); // or something else

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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