RestTemplate结合OkHttp3通用Rest Client客户端
文章目录
一、OkHttp3 Authenticator认证器(仅支持http响应码401和407)
原理
okhttp3.internal.http.RetryAndFollowUpInterceptor
重试拦截器中,判断http响应码若为{@code 401},则在request请求头附带
Basic认证信息
重新发送请求。
package com.example.request.okhttp3;
import okhttp3.*;
import javax.annotation.Nullable;
import java.io.IOException;
/**
* <p> 功能描述: Basic 基本认证
* 注意:http响应码为{@code 401} 时生效,若目标系统自动重定向到登录页面{@code 302}则无法拦截!
* </p>
*
*/
public class BasicAuthenticator implements Authenticator {
private String username;
private String password;
public BasicAuthenticator(String username, String password) {
this.username = username;
this.password = password;
}
/**
* @see okhttp3.internal.http.RetryAndFollowUpInterceptor
*
* @param route
* @param response
* @return
* @throws IOException
*/
@Nullable
@Override
public Request authenticate(@Nullable Route route, Response response) throws IOException {
String credential = Credentials.basic(this.username, this.password);
return response.request().newBuilder().header("Authorization", credential).build();
}
}
final OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.connectionPool(pool())
.connectTimeout(10, TimeUnit.SECONDS)
.callTimeout(5, TimeUnit.MINUTES)
.hostnameVerifier((s, sslSession) -> true)
.authenticator(new BasicAuthenticator("admin","123456"))
.build();
/**
* 连接池
*
* @return 连接池
*/
public ConnectionPool pool() {
return new ConnectionPool(10, 2, TimeUnit.MINUTES);
}
二、RestTemplate basicAuthentication
- 方法1
/**
* basic认证
* {@code RestTemplateBuilder#addClientHttpRequestInitializer(org.springframework.web.client.RestTemplate)}
*/
restTemplate.getClientHttpRequestInitializers()
.add(request -> {
HttpHeaders headers = request.getHeaders();
if (!headers.containsKey(HttpHeaders.AUTHORIZATION)) {
headers.setBasicAuth("admin", "123456");
}
});
- 方法2
final RestTemplate restTemplate = new RestTemplateBuilder()
.basicAuthentication("admin", "123456")
.build();
三、RestTemplate集成OkHttpClient
1.集成OkHttp3
RestTemplate restTemplate = new RestTemplate();
final HttpMessageConverters converters = SpringUtil.getBean(HttpMessageConverters.class);
restTemplate.setMessageConverters(converters.getConverters());
// 切换类库
OkHttpClient okHttpClient = okHttp3Client();
restTemplate.setRequestFactory(new OkHttp3ClientHttpRequestFactory(okHttpClient));
/**
* okHttp3Client 客户端
* {@code https://square.github.io/okhttp/}
*
* @return httpClient
*/
public OkHttpClient okHttp3Client() {
return new OkHttpClient().newBuilder()
.connectionPool(pool())
.connectTimeout(10, TimeUnit.SECONDS)
.callTimeout(5, TimeUnit.MINUTES)
.hostnameVerifier((s, sslSession) -> true)
// 禁止重定向
.followRedirects(false)
.build();
}
/**
* 连接池
*
* @return 连接池
*/
public ConnectionPool pool() {
return new ConnectionPool(10, 2, TimeUnit.MINUTES);
}
2.自定义OkHttpClient拦截器
okhttp3.Interceptor
public OkHttpClient okHttp3Client() {
return new OkHttpClient().newBuilder()
.addInterceptor(chain -> {
Request request = chain.request();
Response response = chain.proceed(request);
if (!response.isSuccessful()) {
// 静默关闭
closeQuietly(response.body());
response = chain.proceed(request);
}
return response;
})
.build();
}
3.自定义RestTemplate拦截器
RestTemplate restTemplate = new RestTemplate();
restTemplate.getInterceptors().add((request, body, execution) -> {
ClientHttpResponse clientHttpResponse = execution.execute(request, body);
if (clientHttpResponse.getStatusCode().is5xxServerError()) {
clientHttpResponse = execution.execute(request, body);
}
return clientHttpResponse;
});
4.集合Spring RetryTemplate框架自动重试
RestTemplate用法-基本认证、JWT Token认证、自动重试
- pom.xml
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.3.1</version>
</dependency>
- 重试代码实现
/**
* 结合RetryTemplate重试框架(编程式方式)
* RetryTemplate重试框声明式注解方式:依赖{@code spring-boot-starter-aop }且重试类必须注入为spring bean
* @param builder
* @return
*/
@Bean
public RestTemplate restTemplate(RestTemplateBuilder builder) {
return builder.setConnectTimeout(Duration.ofSeconds(10))
.setReadTimeout(Duration.ofSeconds(120))
.additionalInterceptors((request, body, execution) -> {
// RetryTemplate 1.3之后支持链式写法
RetryTemplate retryTemplate = RetryTemplate.builder()
.maxAttempts(10)
.exponentialBackoff(100, 2, 10000)
.retryOn(RestClientException.class)
.build();
return retryTemplate.execute(context -> execution.execute(request, body));
})
.build();
}
版权声明:本文为ory001原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。