基于springboot 的 OKHTTP3的封装
1. 在yaml的配置:
根据自己需求配置:
okhttp:
connect-timeout: 200
read-timeout: 200
write-timeout: 200
max-idle-connections: 200
keep-alive-duration: 300
2. (可选)封装一下properties
@Data
@Component
@ConfigurationProperties(prefix = "okhttp")
public class OkHttpProperties {
private int connectTimeout;
private int readTimeout;
private int writeTimeout;
//最大连接池大小
private int maxIdleConnections;
private int keepAliveDuration;
}
3. 配置OKHTTP属性
@Configuration
public class OkHttpConfiguration {
final OkHttpProperties okHttpProperties;
public OkHttpConfiguration(OkHttpProperties okHttpProperties) {
this.okHttpProperties = okHttpProperties;
}
@Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient.Builder()
.sslSocketFactory(sslServerSocketFactory(), x509TrustManager())
.retryOnConnectionFailure(false)
.connectionPool(pool())
.connectTimeout(okHttpProperties.getConnectTimeout(), TimeUnit.SECONDS)
.readTimeout(okHttpProperties.getReadTimeout(), TimeUnit.SECONDS)
.writeTimeout(okHttpProperties.getWriteTimeout(), TimeUnit.SECONDS)
.hostnameVerifier((hostname, session) -> true)
.build();
}
@Bean
public X509TrustManager x509TrustManager() {
return new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
}
@Bean
public SSLSocketFactory sslServerSocketFactory() {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{x509TrustManager()}, new SecureRandom());
return sslContext.getSocketFactory();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
e.printStackTrace();
}
return null;
}
@Bean
public ConnectionPool pool() {
return new ConnectionPool(okHttpProperties.getMaxIdleConnections(), okHttpProperties.getKeepAliveDuration(), TimeUnit.SECONDS);
}
}
4. 封装OkhttpCli
@Slf4j
@Component
public class OkHttpCli {
//定义接收类型
private static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
//注入okHttpClient 配置
private final OkHttpClient okHttpClient;
public OkHttpCli(OkHttpClient okHttpClient) {
this.okHttpClient = okHttpClient;
}
/**
* get 请求
*
* @param url 请求url
* @param params 请求参数
* @param headers 请求头字段
* @return string
*/
public String get(String url, Map<String, String> params, Map<String, String> headers) {
StringBuilder sb = new StringBuilder(url);
if (params != null && params.keySet().size() > 0) {
boolean firstFlag = true;
for (String key : params.keySet()) {
if (firstFlag) {
sb.append("?").append(key).append("=").append(params.get(key));
firstFlag = false;
} else {
sb.append("&").append(key).append("=").append(params.get(key));
}
}
}
Request.Builder builder = new Request.Builder();
if (headers != null && headers.size() > 0) {
for (String key : headers.keySet()) {
builder.addHeader(key, headers.get(key));
}
}
Request request = builder.url(sb.toString()).build();
log.info("现在为get请求, url为{}", sb.toString());
return execute(request);
}
/**
* post 请求
*
* @param url 请求url
* @param params 请求参数map
* @return string
*/
public String post(String url, Map<String, String> params, Map<String, String> headers) {
FormBody.Builder bodyBuilder = new FormBody.Builder();
if (params != null && params.keySet().size() > 0) {
for (String key : params.keySet()) {
bodyBuilder.add(key, params.get(key));
}
}
Request.Builder builder = new Request.Builder();
if (headers != null && headers.size() > 0) {
for (String key : headers.keySet()) {
builder.addHeader(key, headers.get(key));
}
}
Request request = new Request.Builder().url(url).post(bodyBuilder.build()).build();
log.info("现在为post请求,url为{}", url);
return execute(request);
}
/**
* post 请求,请求数据为json的字符串
*
* @param url 请求url地址
* @param json 请求数据
* @return string
*/
public String postJSON(String url, String json) {
log.info("现在为post请求, url 为 {}", url);
return executePost(url, json, JSON, null);
}
/**
* post请求,请求数据为json的字符串和请求头
*
* @param url 请求url地址
* @param json 请求数据
* @param headers 请求头
* @return string
*/
public String postJSON(String url, String json, Map<String, String> headers) {
log.info("现在为postJSON请求, url 为 {}", url);
return executePost(url, json, JSON, headers);
}
private String executePost(String url, String data, MediaType contentType, Map<String, String> headers) {
RequestBody requestBody = RequestBody.create(data, contentType);
Request.Builder builder = new Request.Builder();
if (headers != null && headers.size() > 0) {
for (String key : headers.keySet()) {
builder.addHeader(key, headers.get(key));
}
}
//一般的request为:
//Request request = new Request.Builder().url(url).addHeader(...).post(body).build
Request request = builder.url(url).post(requestBody).build();
return execute(request);
}
// 封装后,判断返回数据的有效性
private String execute(Request request) {
try (Response response = okHttpClient.newCall(request).execute()) {
log.info("response为: {}", response);
ResponseBody responseBody = response.body();
//这里有个坑,response.body().string() string()方法只能调用一次!
//string()方法获取到资源后就释放了,如果不调用这个方法,需要手动释放 response.close()
//所以先取出来保存
String body = "";
if (responseBody != null) {
body = responseBody.string();
log.info("responseBody为:{}", body);
} else {
body = "";
}
return body;
} catch (Exception e) {
throw new RuntimeException("请求出现问题!", e);
}
}
}
5. 使用
String msg = okHttpCli.postJSON(url, requestBody, headers);
只是简单封装了一下,大佬们尽管喷&提出你们宝贵的意见,谢~