Got an issue when using Spring WebClient to consume API.
Code is
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| WebClient.RequestBodySpec requestBodySpec = webClientBuilder.baseUrl(baseUrl).build().post().uri(uri); return requestBodySpec.exchangeToMono(clientResponse -> { if (clientResponse.statusCode().is2xxSuccessful()) { log.info("Successful {} for {}", clientResponse.statusCode().value(), clientResponse.request().getURI()); return clientResponse.bodyToMono(String.class); } else { log.warn("Non-successful code {} for {}", clientResponse.statusCode().value(), clientResponse.request().getURI()); return clientResponse.bodyToMono(String.class) .flatMap(error -> Mono.error(new HttpException(HttpStatus.valueOf(clientResponse.statusCode().value()), "Upstream Error", clientResponse.statusCode().toString(), error) )); } });
|
After testing, the behavior is:
- For 2XX response, no prolem and can get the response.
- Some 4XX/5XX response, some requeses can get the HttpException with
details
- Some 4XX/5XX response, some requests can NOT get the
HttpException.
After some checkings, it shows that
- If the remote server responses a response with body (Like an error
message), no probme;
- If the remote server response an error status but no body, this
issue happens.
After some tries, the solution is that to provide a default response
when the real response is empty (To let the reactive flow to move
on):
1 2 3 4 5 6 7
| return clientResponse.bodyToMono(String.class) .defaultIfEmpty("<Empty>") .flatMap(error -> Mono.error(new HttpException(HttpStatus.valueOf(clientResponse.statusCode().value()), "Upstream Error", clientResponse.statusCode().toString(), error) ));
|