1

使用拦截器,我尝试更新访问令牌。但是代码不起作用...如何使用 http 客户端拦截器更新访问令牌?

try (CloseableHttpClient httpClient = HttpClients.custom().
            addExecInterceptorAfter(ChainElement.PROTOCOL.name(), "a1", (request, scope, chain) -> {
                ClassicHttpResponse response = chain.proceed(request, scope);
                if (response.getCode() == HttpStatus.SC_UNAUTHORIZED) {
                    userAuthBean.updateAccessTokenFromAPI();
                    request.addHeader("Authorization", "Bearer " + userAuthBean.getAccessToken());
                    chain.proceed(request, scope);
                }
                return response;
            })
            .build())
    {
        HttpGet request = new HttpGet(uri);
        request.addHeader("Authorization", "Bearer " + userAuthBean.getAccessToken());
        try (CloseableHttpResponse response = httpClient.execute(request)) {
            HttpEntity entity = response.getEntity();
            if (entity != null) {
                result = EntityUtils.toString(entity, StandardCharsets.UTF_8);
                System.out.println(result);
            }
        } catch (IOException | ParseException ioException) {
            ioException.printStackTrace();
        }
    } catch (IOException e) {
        e.printStackTrace();
    }
    return result;
4

1 回答 1

0

如果获得 403,此代码用于重试请求,理想情况下不应在拦截器中。拦截器通常要直接编写,它操纵当前*请求/响应并导致调用链处理。它们使您的代码变得丑陋,并使调试更加简单明了,因为在大多数情况下,逻辑是隐藏的。

通常,这些拦截器最适合用于记录请求(到 ELK/Kafka 或任何地方),并为通过 http 客户端的每个请求添加缺少的属性/标头(如果有的话)(即使这是一个代码气味 IMO)。

相反,您需要的是Function如下所示的链接,

  public static void main(String[] args) throws IOException {
    getWithAuthTokenRetry.apply(new Request.Builder().url("http://google.com").build());
  }

  public static Function<Request, Response> get =
      (req) -> {
        OkHttpClient okHttpClient = new OkHttpClient();
        Response res = null;
        try {
          res = okHttpClient.newCall(req).execute(); // Simulate calls!!
        } catch (IOException e) {
          e.printStackTrace();
        }
        return res;
      };

  public static Function<Request, Response> getWithAuthTokenRetry =
      request -> {
        Function<Response, Response> authenticateAndRetryFunction =
            res -> {
              if (res != null && res.code() == 200) { //403 Here
                String authToken = "Generated AuthToken"; // Simulating new AuthToken
                Request updatedRequest = request.newBuilder().header("Auth", authToken).build();
                System.out.println(updatedRequest.headers());
                res = get.apply(updatedRequest);
              }
              return res;
            };
        return get.andThen(authenticateAndRetryFunction).apply(request);
      };

这是一个非常广泛的实现,它不能正确处理异常,但我想这些可以根据要求计算出来。

此外,不必为每个请求都创建 ClosableHttpClient,使用 ClosableHttpClient 创建一个 HttpComponentsClientHttpRequestFactory 实例。

于 2021-02-07T12:22:05.990 回答