相关疑难解决方法(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:使用新令牌重试

使用 Spring Boot 2.5,我尝试在构建器级别配置一个 webClient,当它收到 401 时,将删除当前令牌,然后再次尝试调用资源(因此,webclient 意识到不再有令牌,将获取在实际调用资源之前创建一个新资源)。

这是我到目前为止所拥有的:

  @Bean
  WebClient servletWebClient(ClientRegistrationRepository  clientRegistrations,
                      OAuth2AuthorizedClientRepository authorizedClients) {

    //this constructor  will configure internally a RemoveAuthorizedClientOAuth2AuthorizationFailureHandler,
    // and onAuthorizationFailure will be called on it when we get a 401
    var oauth = new ServletOAuth2AuthorizedClientExchangeFilterFunction(clientRegistrations, authorizedClients);

    oauth.setDefaultClientRegistrationId("keycloak");

    return WebClient.builder()
        .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
        .apply(oauth.oauth2Configuration())
        .build();
  }
Run Code Online (Sandbox Code Playgroud)

我可以看到,当使用这个 webClient 时,RemoveAuthorizedClientOAuth2AuthorizationFailureHandler出现在图片中removeAuthorizedClient并被调用。如果我通过此 webClient 进行第二次调用,它会在进行实际调用之前自动获取新令牌。

所以现在,我想配置重试部分,我想一个额外的过滤器可以做到这一点:

  ExchangeFilterFunction retryOn401Function() {

    return (request, next) -> next.exchange(request)
        .flatMap((Function<ClientResponse, Mono<ClientResponse>>) clientResponse -> {
          if (clientResponse.statusCode().value() == 401) {
            log.warn("got an …
Run Code Online (Sandbox Code Playgroud)

spring-boot spring-webflux

8
推荐指数
1
解决办法
2572
查看次数