Spring WebClient嵌套的Mono,根据状态码进行处理

huangapple go评论62阅读模式
英文:

Spring WebClient nested Mono according to status codes

问题

使用WebClient,我想根据HTTP状态代码分别处理ClientResponse。在下面,您可以看到在doOnSuccess的顶部使用了两个新的subscribe()方法。我如何将这些嵌套的Monos传递到WebClient的Mono链中?也就是说,如何消除内部的Monos。

webClient.post()
    .uri(soapServiceUrl)
    .contentType(MediaType.TEXT_XML)
    //.body(Mono.just(req), String.class )
    .body(Mono.just(getCountryRequest), GetCountryRequest.class)
    .exchange()
    .filter((ClientResponse response) -> { return true; })
    .doOnSuccess((ClientResponse response) -> {
        // 嵌套的Mono 1
        if (response.statusCode().is5xxServerError()) {
            response.toEntity(String.class).doOnSuccess(
                error -> {
                    System.out.println("error : " + error);
                }).subscribe();
        }

        // 嵌套的Mono 2
        if (response.statusCode().is2xxSuccessful()) {
            response.toEntity(GetCountryResponse.class).doOnSuccess(
                getCountryResponse -> {
                    System.out.println("success : " + getCountryResponse.getBody().getCountry().getCapital());
                }).subscribe();
        }
    })
    .doOnError((Throwable error) -> {
        System.out.println("getCountryResponse.error : " + error);
    })
    .subscribe();
英文:

Using WebClient I want to handle ClientResponse separately according to HTTP status codes. Below you see two new subscribe() method used in top doOnSuccess. How can I carry those nested Monos to WebClient's Mono chain? That is to say, how to eliminate inner monos.

webClient.post()
            .uri( soapServiceUrl )
            .contentType(MediaType.TEXT_XML)
            //.body(Mono.just(req), String.class )
            .body( Mono.just(getCountryRequest) , GetCountryRequest.class  )
            .exchange()
            .filter( (ClientResponse response) -> { return true; } )
            .doOnSuccess( (ClientResponse response) -> {
                //nested mono 1
                if( response.statusCode().is5xxServerError() ){
                    response.toEntity(String.class).doOnSuccess(
                            error -> {
                                System.out.println("error : "+ error);
                            }).subscribe();
                }

                //nested mono 2
                if( response.statusCode().is2xxSuccessful() ){
                    response.toEntity(GetCountryResponse.class).doOnSuccess(
                            getCountryResponse -> {
                                System.out.println("success : "+ getCountryResponse.getBody().getCountry().getCapital());
                            }).subscribe();
                }
            })
            .doOnError( (Throwable error) -> {
                System.out.println( "getCountryResponse.error : "+ error );
            })
            .subscribe();

答案1

得分: 1

WebClient的“retrieve()”方法有更好的处理错误代码的方式。

我会这样做:

```java
webClient.post()
            .uri(soapServiceUrl)
            .contentType(MediaType.TEXT_XML)
            //.body(Mono.just(req), String.class )
            .body(Mono.just(getCountryRequest), GetCountryRequest.class)
            .retrieve()
            .onStatus(
                HttpStatus::isError,
                clientResponse -> clientResponse
                    // 将错误响应体作为字符串获取
                    .bodyToMono(String.class)
                    // 将errorResponseBody映射为新的错误信号
                    .flatMap(
                        errorResponseBody -> Mono.error(
                            new ResponseStatusException(
                                clientResponse.statusCode(),
                                errorResponseBody))))
            // 将成功响应获取为Mono<GetCountryResponse>
            .bodyToMono(GetCountryResponse.class)
            .doOnSuccess(response ->
                System.out.println("success : " +
                    response.getBody().getCountry().getCapital()))
            // 现在将会记录响应错误
            .doOnError(ResponseStatusException.class, error -> {
                System.out.println("getCountryResponse.error : " + error);
            })
            .subscribe();

<details>
<summary>英文:</summary>

The Webclient&#39;s ``retrieve()`` method has better ways to handle error codes.

I would do it like this: 

webClient.post()
.uri( soapServiceUrl )
.contentType(MediaType.TEXT_XML)
//.body(Mono.just(req), String.class )
.body( Mono.just(getCountryRequest) , GetCountryRequest.class )
.retrieve()
.onStatus(
HttpStatus::isError,
clientResponse ->
clientResponse
//get the error response body as a string
.bodyToMono(String.class)
//flatmap the errorResponseBody into a new error signal
.flatMap(
errorResponseBody ->
Mono.error(
new ResponseStatusException(
clientResponse.statusCode(),
errorResponseBody))))

        //get success response as Mono&lt;GetCountryResponse&gt;
        .bodyToMono(GetCountryResponse.class)
        .doOnSuccess( (GetCountryResponse response) -&gt;
               System.out.println(&quot;success : &quot; + 
                response.getBody().getCountry().getCapital()))
        //Response errors will now be logged below
        .doOnError(ResponseStatusException.class, error -&gt; {
            System.out.println( &quot;getCountryResponse.error : &quot;+ error );
        })
        .subscribe();

</details>



huangapple
  • 本文由 发表于 2020年8月20日 00:13:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/63491043.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定