JavaEar 专注于收集分享传播有价值的技术资料

Spring Webflux : Webclient : Get body on error

I am using the webclient from spring webflux, like this :

WebClient.create()
            .post()
            .uri(url)
            .syncBody(body)
            .accept(MediaType.APPLICATION_JSON)
            .headers(headers)
            .exchange()
            .flatMap(clientResponse -> clientResponse.bodyToMono(tClass));

It is working well. I now want to handle the error from the webservice I am calling (Ex 500 internal error). Normally i would add an doOnError on the "stream" and isu the Throwable to test the status code,

But my issue is that I want to get the body provided by the webservice because it is providing me a message that i would like to use.

I am looking to do the flatMap whatever happen and test myself the status code to deserialize or not the body.

3个回答

    最佳答案
  1. I do something like this:

    Mono<ClientResponse> responseMono = requestSpec.exchange()
                .doOnNext(response -> {
                    HttpStatus httpStatus = response.statusCode();
                    if (httpStatus.is4xxClientError() || httpStatus.is5xxServerError()) {
                        throw new WebClientException(
                                "ClientResponse has erroneous status code: " + httpStatus.value() +
                                        " " + httpStatus.getReasonPhrase());
                    }
                });
    

    and then:

    responseMono.subscribe(v -> { }, ex -> processError(ex));
    
  2. 参考答案2
  3. We have finally understood what is happening : By default the Netty's httpclient (HttpClientRequest) is configured to fail on server error (response 5XX) and not on client error (4XX), this is why it was always emitting an exception.

    What we have done is extend AbstractClientHttpRequest and ClientHttpConnector to configure the httpclient behave the way the want and when we are invoking the WebClient we use our custom ClientHttpConnector :

     WebClient.builder().clientConnector(new CommonsReactorClientHttpConnector()).build();
    
  4. 参考答案3