相关疑难解决方法(0)

添加重试WebClient的所有请求

我们有一个服务器来检索OAUTH令牌,并且通过WebClient.filter方法将oauth令牌添加到每个请求中,例如

webClient
                .mutate()
                .filter((request, next) -> tokenProvider.getBearerToken()
                        .map(token -> ClientRequest.from(request)
                                .headers(httpHeaders -> httpHeaders.set("Bearer", token))
                                .build()).flatMap(next::exchange))
                .build();
TokenProvider.getBearerToken returns Mono<String> since it is a webclient request (this is cached)
Run Code Online (Sandbox Code Playgroud)

我想要重试功能,发生401错误,将使令牌无效并再次尝试请求,我这样工作

webClient.post()
            .uri(properties.getServiceRequestUrl())
            .contentType(MediaType.APPLICATION_JSON)
            .body(fromObject(createRequest))
            .retrieve()
            .bodyToMono(MyResponseObject.class)
            .retryWhen(retryOnceOn401(provider))

private Retry<Object> retryOnceOn401(TokenProvider tokenProvider) {
        return Retry.onlyIf(context -> context.exception() instanceof WebClientResponseException && ((WebClientResponseException) context.exception()).getStatusCode() == HttpStatus.UNAUTHORIZED)
                .doOnRetry(objectRetryContext -> tokenProvider.invalidate());
    }
Run Code Online (Sandbox Code Playgroud)

有没有办法将其移至webClient.mutate()..... build()函数?这样所有请求都将具有此重试功能?

我尝试添加作为过滤器,但似乎没有用,例如

.filter(((request, next) -> next.exchange(request).retryWhen(retryOnceOn401(tokenProvider))))
Run Code Online (Sandbox Code Playgroud)

对解决此问题的最佳方法有何建议?问候

project-reactor spring-webflux

8
推荐指数
2
解决办法
5622
查看次数

Spring WebClient:重试中调用方法

我一直在寻找以下用例的解决方案但没有成功,我希望有人可以提供帮助:

假设以下用例。我需要调用客户 Api( customerApi),而该 api 需要一个Bearer令牌,当我调用时该令牌可能已过期customerApi。如果令牌已过期,则customerApi返回401响应。

我想做的是,如果我收到一个401并调用该方法来获取新Bearer令牌,则仅重试一次。如果重试仍然返回401,我需要抛出一个Exception

获取token的方法Bearer

private String getToken() {
    return oAuthService.getToken();
}
Run Code Online (Sandbox Code Playgroud)

webClient调用customerApi(customerWebClient是用 ) 创建的 bean 的用法WebClient.Builder

public Customer getCustomerById(String customerId, String token) {
        return customerWebClient.get()
            .uri("myurl/customers/{customerId}, customerId)
            .headers(httpHeaders -> {
                httpHeaders.add(HttpHeaders.AUTHORIZATION, "Bearer " + token);
            })
            .retrieve()
            .bodyToMono(Customer.class)
            .onErrorResume(WebClientResponseException.NotFound.class, notFound ->
                        Mono.error(new MyCustomException()))
            .block();
    }
Run Code Online (Sandbox Code Playgroud)

看来retryWhen只能用超时来升级了。所以我希望有人知道如何实现这个用例^^

感谢您的帮助 :)

编辑 …

reactor-netty spring-webflux spring-webclient

3
推荐指数
1
解决办法
2906
查看次数