使用新的请求拦截器来假设客户端重试程序?

Mik*_*ger 9 java interceptor spring-cloud-feign feign

我目前正在手动构建一个假装客户端并将拦截器传递给它进行授权.我想为一些响应代码提供更智能的Retryer.

public class myErrorEncoder extends ErrorDecoder.Default {

@Override
public Exception decode(final String methodKey, final Response response) {
    if (response.status() == 401) {
        String token = refreshToken();  // I would like to refresh the token and Edit the client
        return new RetryableException("Token Expired will retry it", null);
    } else {
        return super.decode(methodKey, response);
    }
}
Run Code Online (Sandbox Code Playgroud)

}

拦截器

@Bean public CustomInterceptor getInterceptor(String token) {
    return new CustomInterceptor(token);}
Run Code Online (Sandbox Code Playgroud)

假装建设者

 private <T> T feignBuild(final Class<T> clazz, final String uri, final String token) {
    return Feign
            .builder().client(new ApacheHttpClient())
            .encoder(new GsonEncoder())
            .decoder(new ResponseEntityDecoder(feignDecoder())
            .retryer(new Retryer.Default(1,100,3))
            .errorDecoder(new ErrorDecoder())
            .requestInterceptor(getInterceptor(token))
            .contract(new ClientContract())
            .logger(new Slf4jLogger(clazz)).target(clazz, uri);
}
Run Code Online (Sandbox Code Playgroud)

现在我想用刷新的令牌更新假装客户端并重试.有没有办法访问客户端实例并进行配置.

Kev*_*vis 0

您对拦截器的使用不正确。拦截器在重试期间重新应用,但它们仅实例化一次,并且预计是线程安全的。为了实现您正在寻找的目标,需要将令牌生成与拦截器分开,并让拦截器请求新令牌。

public class TokenInterceptor() {
   TokenService tokenService;

   public TokenInterceptor(TokenService tokenService) {
      this.tokenService = tokenService;
   }

   public void apply(RequestTemplate template) {
      /* getToken() should create a new token */
      String token = this.tokenService.getToken();
      template.header("Authorization", "Bearer " + token);
   }
}
Run Code Online (Sandbox Code Playgroud)

这将确保每个重试周期都会创建一个新令牌。