gpt4 book ai didi

spring-webflux - Spring Web 客户端 : Call method in retry

转载 作者:行者123 更新时间:2023-12-02 19:10:31 25 4
gpt4 key购买 nike

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

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

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

获取Bearer token 的方法:

private String getToken() {
return oAuthService.getToken();
}

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

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();
}

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

感谢您的帮助:)

编辑:

我尝试使用 reactor-extra 中的 retryWhen(Retry.onlyIf(...)) 但是旧的 retryWhen 来自这个软件包现已弃用(解决方案基于:Adding a retry all requests of WebClient)

最佳答案

方法

public final Mono<T> retryWhen(Function<Flux<Throwable>, ? extends Publisher<?>> whenFactory)

已被弃用,现在首选方法是

public final Mono<T> retryWhen(Retry retrySpec)

因此,您可以将代码修改为类似这样的内容,以使其适用于新的 retryWhen

public Customer getCustomerById(String customerId, String token) {

HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + token);

final RetrySpec retrySpec = Retry.max(1).doBeforeRetry(
retrySignal -> headers.add(HttpHeaders.AUTHORIZATION, "Bearer " + someTokenGetterMethod()))
.filter(throwable -> throwable.getClass() == Unauthorized.class);

return Mono.defer(() -> webClient.get().uri("myurl/customers/{customerId}, customerId")
.headers(httpHeaders -> httpHeaders.addAll(headers))
.retrieve()
.bodyToMono(Customer.class))
.retryWhen(retrySpec)
.onErrorResume(WebClientResponseException.NotFound.class,
notFound -> Mono.error(new MyCustomException()))
.block();
}

这是一个使用 https://httpbin.org/ 的工作示例

public CommandLineRunner commandLineRunner() {

HttpHeaders headers = new HttpHeaders();

final RetrySpec retrySpec = Retry.max(1).doBeforeRetry(
retrySignal -> headers.add("Authorization", "Bearer 1234")).filter(
throwable -> throwable.getClass() == Unauthorized.class);

return args -> Mono.defer(() -> webClient.get().uri("https://httpbin.org/bearer")
.headers(httpHeaders -> httpHeaders.addAll(headers)).retrieve().toEntity(Map.class)
.retryWhen(retrySpec)
.subscribe(objectResponseEntity -> System.out
.println("objectResponseEntity = " + objectResponseEntity.getBody()));
}

此外,我认为您在重试添加授权 token 时尝试操纵 header 的方式不是实现此目的的正确方法。您必须提出更好的解决方案/设计。

关于spring-webflux - Spring Web 客户端 : Call method in retry,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64355088/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com