【问题标题】:Catch authentication exceptions捕获身份验证异常
【发布时间】:2020-01-01 02:49:13
【问题描述】:

我使用此代码发送 XML 请求:

RestClient client = RestClientBuilder.builder()
                        .gatewayUrl(URL) 
                        .build();
Mono<AuthorizeResponse> result = client.executeAndReceiveAuthorize(request);
                response = result.block();

 public RestClient(String gatewayUrl, String token, String username, String password, SslContext sslContext) {
        this.token = token;
        this.gatewayUrl = gatewayUrl;
        WebClient.Builder builder = WebClient.builder().baseUrl(gatewayUrl);
        if (sslContext != null) {
            HttpClient httpClient = HttpClient.create().secure(sslContextSpec -> sslContextSpec.sslContext(sslContext));
            ClientHttpConnector httpConnector = new ReactorClientHttpConnector(httpClient);
            builder.clientConnector(httpConnector);
        }
        if (username != null && password != null) {
            builder.filter(basicAuthentication(username, password));
        }
        client = builder.build();
    }

    public Mono<AuthorizeResponse> executeAndReceiveAuthorize(AuthorizeRequest transaction) {
        Mono<AuthorizeRequest> transactionMono = Mono.just(transaction);
        return client.post().uri(checkTrailingSlash(gatewayUrl) + token)
                .header(HttpHeaders.USER_AGENT, "Mozilla/5.0")
                .accept(MediaType.APPLICATION_XML)
                .contentType(MediaType.APPLICATION_XML)
                .body(transactionMono, AuthorizeRequest.class)
                .retrieve()
                .bodyToMono(AuthorizeResponse.class);
    }

但有时我会收到此错误:

org.springframework.web.reactive.function.client.WebClientResponseException$Unauthorized: 401 Unauthorized
 at java.base/java.lang.Thread.run(Thread.java:834)
2019-08-27 22:05:45,720 ERROR [stderr] (processingTransactionGenesisAuthorizeContainer-1)       Suppressed: java.lang.Exception: #block terminated with an error
 Caused by: java.lang.NullPointerException: null

当我收到错误 401 时如何捕获和处理异常? 如果可能的话,我想在response = result.block(); 行之后处理异常。

【问题讨论】:

  • 您是否尝试过对Mono 使用onError 处理程序?

标签: java spring spring-boot spring-webflux


【解决方案1】:

首先,在响应式代码中显式使用block 并不是一个好主意。这背后的原因是,它将代码变成了阻塞,这不是反应流应该如何工作的。所以,请删除response = result.block();

现在,如果您想处理特定状态,则可以修改您的 executeAndReceiveAuthorize 方法以使用 WebClient 的 onStatus(Predicate&lt;HttpStatus&gt; var1, Function&lt;ClientResponse, Mono&lt;? extends Throwable&gt;&gt; var2)

public Mono<AuthorizeResponse> executeAndReceiveAuthorize (AuthorizeRequest transaction){

    Mono<AuthorizeRequest> transactionMono = Mono.just(transaction);

    return client.post().uri(checkTrailingSlash(gatewayUrl) + token)
        .header(HttpHeaders.USER_AGENT, "Mozilla/5.0").accept(MediaType.APPLICATION_XML)
        .contentType(MediaType.APPLICATION_XML).body(transactionMono, AuthorizeRequest.class)
        .retrieve().onStatus(status -> status == HttpStatus.UNAUTHORIZED, clientResponse -> Mono
            .error(new SomeCustomAuthorizationException("Some failure exception")))
        .bodyToMono(AuthorizeResponse.class);
}

【讨论】:

    【解决方案2】:

    在mono 上定义doOnError 怎么样?

    例如:

    Mono<AuthorizeResponse> result = client.executeAndReceiveAuthorize(request);
    response = result.doOnError(e -> {
                          throw new RuntimeException(e);
                      })
                     .block();
    

    如果您需要访问 json 响应,请检查此answer。

    【讨论】:

    • doOnError 是 Spring Webflux 中的副作用方法,不应用于这些目的。它更适合记录相关的工作。此外,抛出异常是一个坏主意,我们应该包装异常,如return Mono.error(new Exception())
    • 抛出异常只是处理异常的一个示例。重要的部分是异常被传递到doOnError 方法中,并且可以从那里获取。 @PeterPenzov 并没有真正指定他想要处理的异常,也许记录它就足够了。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-10
    • 2012-01-07
    • 1970-01-01
    • 1970-01-01
    • 2017-07-02
    相关资源
    最近更新 更多