在 apache httpclient 中通过拦截器刷新访问令牌
Refresh Access Token via Interceptor in apache httpclient
使用拦截器,我尝试更新访问令牌。但是代码不起作用...如何使用 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;
此代码用于在获得 403 的情况下重试请求,理想情况下不应在拦截器中。拦截器通常要直接编写,它会操纵 current* request/response 并导致调用链进行处理。它们使您的代码变得丑陋,并使调试变得更加简单,因为在大多数情况下,逻辑是隐藏的。
一般来说,这些拦截器最好用于记录请求(至 ELK/Kafka 或任何地方)并为 *every 添加缺失的 attributes/headers(如果有的话)请求通过 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 实例。
使用拦截器,我尝试更新访问令牌。但是代码不起作用...如何使用 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;
此代码用于在获得 403 的情况下重试请求,理想情况下不应在拦截器中。拦截器通常要直接编写,它会操纵 current* request/response 并导致调用链进行处理。它们使您的代码变得丑陋,并使调试变得更加简单,因为在大多数情况下,逻辑是隐藏的。
一般来说,这些拦截器最好用于记录请求(至 ELK/Kafka 或任何地方)并为 *every 添加缺失的 attributes/headers(如果有的话)请求通过 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 实例。