当我使用HttpClient配置RestTemplate时,我的拦截器仅在第一次执行,第二次在执行时挂断,在下面的此块中。也不例外,我不知道为什么!
如果我删除httpClient则没有问题。
(我的拦截器意图是捕获401未经授权的状态以刷新访问令牌)
if (url.contains("/auth") || url.contains("/custcare-common")) {
return execution.execute(request, body);
}
完整代码如下:
public class RestTemplateHeaderInterceptor implements ClientHttpRequestInterceptor {
@Override
public ClientHttpResponse intercept(HttpRequest request, byte[] body, ClientHttpRequestExecution execution)
throws IOException {
String url = request.getURI().getPath();
if (url.contains("/auth") || url.contains("/custcare-common")) {
return execution.execute(request, body);
}
HttpSession session = SessionBean.getSession();
if (session != null) {
// check header does not has token then add to header
if (request.getHeaders().isEmpty() || !request.getHeaders().containsKey(HttpHeaders.AUTHORIZATION)) {
// add jwt token to header
Object accessToken = session.getAttribute(AppConstants.Token.ACCESS_TOKEN);
if (accessToken != null) {
request.getHeaders().add(HttpHeaders.AUTHORIZATION, SecurityConstants.TOKEN_PREFIX + accessToken);
}
}
// refresh token when expire
ClientHttpResponse response = execution.execute(request, body);
if (response.getStatusCode() == HttpStatus.UNAUTHORIZED) {
Object refreshToken = session.getAttribute(AppConstants.Token.REFRESH_TOKEN);
if (refreshToken != null) {
TokenData newTokenData = getNewToken(refreshToken.toString());
if (newTokenData != null) {
session.setAttribute(AppConstants.Token.ACCESS_TOKEN, newTokenData.getAccessToken());
session.setAttribute(AppConstants.Token.REFRESH_TOKEN, newTokenData.getRefreshToken());
request.getHeaders().set(HttpHeaders.AUTHORIZATION, SecurityConstants.TOKEN_PREFIX + newTokenData.getAccessToken());
return execution.execute(request, body);
}
}
}
}
return execution.execute(request, body);
}
private TokenData getNewToken(String refreshToken) {
TokenData tokenData = null;
RefreshTokenRequest request = new RefreshTokenRequest();
request.setRefreshToken(refreshToken);
MessagesResponse<TokenData> response = RestUtil.post(RestUtil.getCcApiUrl("cc-api.authen.refresh-token"), request, new ParameterizedTypeReference<MessagesResponse<TokenData>>() {});
if (response != null) {
tokenData = response.getData();
}
return tokenData;
}
}
我的RestTemplate配置:
@Configuration
public class RestTemplateConfig {
@Bean
public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
PoolingHttpClientConnectionManager result = new PoolingHttpClientConnectionManager();
result.setMaxTotal(20);
return result;
}
@Bean
public RequestConfig requestConfig() {
RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(60000).setConnectTimeout(60000)
.setSocketTimeout(60000).build();
return requestConfig;
}
@Bean
public CloseableHttpClient httpClient() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
TrustStrategy trustStrategy = new TrustStrategy() {
@Override
public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
return true;
}
};
SSLContext sslContext = SSLContexts.custom().loadTrustMaterial(null, trustStrategy).build();
SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext, new NoopHostnameVerifier());
CloseableHttpClient result = HttpClientBuilder.create()
.setConnectionManager(poolingHttpClientConnectionManager())
.setDefaultRequestConfig(requestConfig())
.setSSLSocketFactory(csf)
.build();
return result;
}
@Bean
@Primary
public RestTemplate restTemplate() throws KeyManagementException, NoSuchAlgorithmException, KeyStoreException {
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient());
RestTemplate restTemplate = new RestTemplate(requestFactory);
restTemplate.setErrorHandler(new RestResponseErrorHandler());
List<ClientHttpRequestInterceptor> interceptors = restTemplate.getInterceptors();
if (interceptors.isEmpty()) {
interceptors = new ArrayList<>();
}
interceptors.add(new RestTemplateHeaderInterceptor());
restTemplate.setInterceptors(interceptors);
return restTemplate;
}
}
最后,我通过设置DefaultMaxPerRoute处理了此问题,但我对此仍然感到困惑。 :D
@Bean
public PoolingHttpClientConnectionManager poolingHttpClientConnectionManager() {
PoolingHttpClientConnectionManager result = new PoolingHttpClientConnectionManager();
result.setMaxTotal(100);
result.setDefaultMaxPerRoute(100);
return result;
}
最佳答案
你可以试试这个吗
而不是下面的代码块即
HttpComponentsClientHttpRequestFactory requestFactory = new HttpComponentsClientHttpRequestFactory(httpClient());
RestTemplate restTemplate = new RestTemplate(requestFactory);
尝试
RestTemplate restTemplate = new RestTemplate();
restTemplate.setRequestFactory(new BufferingClientHttpRequestFactory(clientHttpRequestFactory()));
看看这是否适合您。
关于java - Spring RestTemplate拦截器不执行请求,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59244512/