1.引入okhttp依赖
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>3.14.9</version>
</dependency>
2.注入bean和依赖配置信息
applcation.yml配置
okhttp:
connect-timeout: 30
read-timeout: 60
write-timeout: 60
keep-alive-duration: 300
max-idle-connections: 30
import okhttp3.ConnectionPool;
import okhttp3.OkHttpClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.concurrent.TimeUnit;
/**
*
* @description:
* @author: zhuyu
* @date: 2022/4/8 10:21
*/
@Configuration
public class OkHttpConfiguration {
@Autowired
BusinessParamConfig paramConfig;
/**
* 连接超时时间(单位:秒)
*/
@Value("${okhttp.connect-timeout}")
private Integer connectTimeout;
/**
* 读超时时间(单位:秒)
*/
@Value("${okhttp.read-timeout}")
private Integer readTimeout;
/**
* 写超时时间(单位:秒)
*/
@Value("${okhttp.write-timeout}")
private Integer writeTimeout;
/**
* 连接池中整体的空闲连接的最大数量
*/
@Value("${okhttp.max-idle-connections}")
private Integer maxIdleConnections;
/**
* 连接空闲时间最多为 300 秒
*/
@Value("${okhttp.keep-alive-duration}")
private Long keepAliveDuration;
@Bean
public OkHttpClient okHttpClient() {
return new OkHttpClient.Builder()
.sslSocketFactory(sslSocketFactory(), x509TrustManager())
// 是否开启缓存
.retryOnConnectionFailure(false)
.connectionPool(pool())
.connectTimeout(connectTimeout, TimeUnit.SECONDS)
.readTimeout(readTimeout, TimeUnit.SECONDS)
.writeTimeout(writeTimeout,TimeUnit.SECONDS)
.hostnameVerifier((hostname, session) -> true)
// 设置代理
// .proxy(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 8888)))
// 拦截器
.addInterceptor(new OkHttpInterceptor(paramConfig))
.build();
}
@Bean
public X509TrustManager x509TrustManager() {
return new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}
};
}
@Bean
public SSLSocketFactory sslSocketFactory() {
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(maxIdleConnections, keepAliveDuration, TimeUnit.SECONDS);
}
}
3.添加okhttp拦截器,可以统一添加header头信息
import com.common.config.BusinessParamConfig;
import com.util.LogUtil;
import okhttp3.Interceptor;
import okhttp3.Request;
import okhttp3.Response;
import org.apache.commons.lang3.StringUtils;
import java.io.IOException;
/**
* TODO
*
* @description:
* @author: zhuyu
* @date: 2022/4/18 11:24
*/
public class OkHttpInterceptor implements Interceptor {
//注入业务配置组件
BusinessParamConfig paramConfig;
public OkHttpInterceptor(BusinessParamConfig paramConfig){
this.paramConfig = paramConfig;
}
@Override
public Response intercept(Chain chain) throws IOException {
Request request = chain.request();
//http请求添加统一headers
Request.Builder builder = request.newBuilder();
//此处最好先判断是否包含Content-Type,再添加,因为文件上传的Content-Type是multipart/form-data;
builder.addHeader("Content-Type", "application/json; charset=UTF-8");
if(StringUtils.isNotBlank(paramConfig.groupApiToken)){
builder.addHeader("api-key", paramConfig.groupApiToken);
}
request = builder.build();
try {
return chain.proceed(request);
} catch (Exception e) {
throw e;
}
}
}
4.添加公用模版方法 OkHttpTemplate
import com.alibaba.fastjson.JSON;
import okhttp3.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
/**
* OkHttp请求工具服务类
*
* @description:
* @author: zhuyu
* @date: 2022/4/8 10:46
*/
@Component
public class OkHttpTemplate {
@Resource
OkHttpClient okHttpClient;
private OkHttpTemplate(){}
private static Logger logger = LoggerFactory.getLogger(OkHttpTemplate.class);
/**
* "application/x-www-form-urlencoded",是默认的MIME内容编码类型,一般可以用于所有的情况,但是在传输比较大的二进制或者文本数据时效率低。
* 这时候应该使用"multipart/form-data"。如上传文件或者二进制数据和非ASCII数据。
*/
public static final MediaType MEDIA_TYPE_NORAML_FORM = MediaType.parse("application/x-www-form-urlencoded;charset=utf-8");
public static final MediaType MEDIA_TYPE_MULTIPART_FORM = MediaType.parse("multipart/form-data;");
public static final MediaType MEDIA_TYPE_STREAM = MediaType.parse("application/octet-stream");
public static final MediaType MEDIA_TYPE_JSON = MediaType.parse("application/json;charset=utf-8");
/**
* 自定义回调接口
*/
public interface NetCall {
void success(Call call, Response response) throws IOException;
void failed(Call call, IOException e);
}
public Request.Builder getRequestBuilder(){
return new Request.Builder();
}
public Request.Builder getRequestBuilder(Map<String, String> headers){
Request.Builder builder = getRequestBuilder();
if(headers != null){
for (Map.Entry<String,String> item : headers.entrySet()){
builder.addHeader(item.getKey(), item.getValue());
}
}
return builder;
}
/**
* get请求
*
* @param url
* @return
*/
public String doGet(String url) {
return doGet(url, null);
}
/**
* get请求
*
* @param url
* @param headers
* @return
*/
public String doGet(String url, Map<String, String> headers) {
String result = "";
try {
//1 构造Request
Request.Builder builder = getRequestBuilder(headers);
Request request = builder.get().url(url).build();
//2 将Request封装为Call
Call call = okHttpClient.newCall(request);
//3 执行Call,得到response
Response response = call.execute();
if (response.isSuccessful()) {
result = response.body().string();
}
} catch (Exception e) {
logger.error("doGet, url = " + url, e);
}
return result;
}
/**
* get请求,异步回调
*
* @param url
* @param headers
* @param netCall
* @return
*/
public void doGetAsync(String url, Map<String, String> headers, final NetCall netCall) {
try {
//1 构造Request
Request.Builder builder = getRequestBuilder(headers);
Request request = builder.get().url(url).build();
//2 将Request封装为Call
Call call = okHttpClient.newCall(request);
//3 执行Call
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
netCall.failed(call, e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
netCall.success(call, response);
}
});
} catch (Exception e) {
logger.error("doGetAsync, url = " + url, e);
}
}
/**
* post请求,同步方式
*
* @param url
* @param bodyParams
* @return
*/
public String doPost(String url, Map<String, String> bodyParams) {
return doPost(url, null, bodyParams);
}
/**
* post请求,同步方式
*
* @param url
* @param bodyParams
* @param headers
* @return
*/
public String doPost(String url, Map<String, String> headers, Map<String, String> bodyParams) {
String result = "";
try {
Request request = buildRequest(url, headers, bodyParams);
//3 将Request封装为Call
Call call = okHttpClient.newCall(request);
//4 执行Call,得到response
Response response = call.execute();
if (response.isSuccessful()) {
result = response.body().string();
}
} catch (Exception e) {
logger.error("doPost, url = " + url + " , params : " + JSON.toJSONString(bodyParams), e);
}
return result;
}
/**
* post请求,异步回调
*
* @param url
* @param bodyParams
* @param netCall
*/
public void doPostAsync(String url, Map<String, String> bodyParams, final NetCall netCall) {
doPostAsync(url, null, bodyParams, netCall);
}
/**
* post请求,异步回调
*
* @param url
* @param bodyParams
* @param headers
* @param netCall
*/
public void doPostAsync(String url, Map<String, String> headers, Map<String, String> bodyParams, final NetCall netCall) {
try {
Request request = buildRequest(url, headers, bodyParams);
//3 将Request封装为Call
Call call = okHttpClient.newCall(request);
//4 执行Call
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
netCall.failed(call, e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
netCall.success(call, response);
}
});
} catch (Exception e) {
logger.error("doPostAsync, url = " + url + " , params : " + JSON.toJSONString(bodyParams), e);
}
}
/**
* post请求
*
* @param url
* @param json
* @return
* @throws IOException
*/
public String postJson(String url, String json) {
return postJson(url, json, null);
}
/**
* post请求
*
* @param url
* @param json
* @param headers
* @return
*/
public String postJson(String url, String json, Map<String, String> headers) {
String result = "";
try {
Request request = buildRequest(url, headers, json);
Response response = okHttpClient.newCall(request).execute();
if (response.isSuccessful()) {
result = response.body().string();
}
} catch (Exception e) {
logger.error("postJson, url = " + url + " , json : " + json + " , headers : " + JSON.toJSONString(headers), e);
}
return result;
}
/**
* post请求,异步回调
*
* @param url
* @param json
* @param netCall
* @throws IOException
*/
public void postJsonAsync(String url, String json, final NetCall netCall) {
postJsonAsync(url, json, null, netCall);
}
/**
* post请求,异步回调
*
* @param url
* @param json
* @param netCall
* @throws IOException
*/
public void postJsonAsync(String url, String json, Map<String, String> headers, final NetCall netCall) {
try {
//2 构造Request
Request request = buildRequest(url, headers, json);
//3 将Request封装为Call
Call call = okHttpClient.newCall(request);
//4 执行Call
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
netCall.failed(call, e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
netCall.success(call, response);
}
});
} catch (Exception e) {
logger.error("postJsonAsync, url = " + url + " , json : " + json + " , headers : " + JSON.toJSONString(headers) , e);
}
}
/**
* put请求
*
* @param url
* @param json
* @return
* @throws IOException
*/
public String putJson(String url, String json) {
return putJson(url, json, null);
}
/**
* put请求
*
* @param url
* @param json
* @param headers
* @return
*/
public String putJson(String url, String json, Map<String, String> headers) {
String result = "";
try {
//1构造RequestBody
RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, json);
Request.Builder builder = getRequestBuilder(headers);
//2 构造Request
Request request = builder.url(url).put(body).build();
Response response = okHttpClient.newCall(request).execute();
if (response.isSuccessful()) {
result = response.body().string();
}
} catch (Exception e) {
logger.error("putJson, url = " + url + " , json : " + json + " , headers : " + JSON.toJSONString(headers), e);
}
return result;
}
/**
* post文件上传
*
* @param url 接口地址
* @param headers headers参数
* @param params 参数
* @param fileKey 服务端接口参数key
* @param files 文件集合
*/
public String postFileUpload(String url, Map<String, String> headers, Map<String, String> params, String fileKey, List<File> files) {
String result = "";
try {
// form 表单形式上传
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
//添加参数
if (params != null) {
for (Map.Entry<String, String> entry : params.entrySet()) {
builder.addFormDataPart(entry.getKey(), entry.getValue());
}
}
//添加文件,并约定key如“upload”作为后台接受的参数key
if (files != null) {
for (File file : files) {
builder.addFormDataPart(fileKey, file.getName(), RequestBody.create(MEDIA_TYPE_MULTIPART_FORM, file));
}
}
RequestBody requestBody = builder.build();
Request.Builder requestBuilder = getRequestBuilder(headers);
requestBuilder.addHeader("Content-Type","multipart/form-data;");
Request request = requestBuilder.url(url).post(requestBody).build();
Response response = okHttpClient.newCall(request).execute();
if (response != null && response.isSuccessful()) {
result = response.body().string();
}
} catch (Exception e) {
logger.error("postFileUpload, url = " + url + " , params : " + JSON.toJSONString(params) , e);
}
return result;
}
/**
* post文件上传
*
* @param url 接口地址
* @param headers headers参数
* @param params 参数
* @param fileKey 服务端接口参数key
* @param files 文件集合
* @param netCall 回调函数
*/
public void postFileUploadAsync(String url, Map<String, String> headers, Map<String, String> params, String fileKey, List<File> files,final NetCall netCall) {
try {
MultipartBody.Builder builder = new MultipartBody.Builder();
builder.setType(MultipartBody.FORM);
//添加参数
if (params != null) {
for (Map.Entry<String, String> entry : params.entrySet()) {
builder.addFormDataPart(entry.getKey(), entry.getValue());
}
}
//添加文件,并约定key如“upload”作为后台接受的参数key
if (files != null) {
for (File file : files) {
builder.addFormDataPart(fileKey, file.getName(), RequestBody.create(MEDIA_TYPE_MULTIPART_FORM, file));
}
}
RequestBody requestBody = builder.build();
Request.Builder requestBuilder = getRequestBuilder(headers);
requestBuilder.addHeader("Content-Type","multipart/form-data;");
Request request = requestBuilder.url(url).post(requestBody).build();
Call call = okHttpClient.newCall(request);
//4 执行Call
call.enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
netCall.failed(call, e);
}
@Override
public void onResponse(Call call, Response response) throws IOException {
netCall.success(call, response);
}
});
} catch (Exception e) {
logger.error("postFileUploadAsync, url = " + url + " , params : " + JSON.toJSONString(params) , e);
}
}
/**
* buildRequest by json
* @param url
* @param headers
* @param json
* @return
*/
public Request buildRequest(String url, Map<String, String> headers, String json) {
//1构造RequestBody
RequestBody body = RequestBody.create(MEDIA_TYPE_JSON, json);
Request.Builder builder = getRequestBuilder(headers);
//2 构造Request
Request request = builder.url(url).post(body).build();
return request;
}
/**
* buildRequest by map
* @param url
* @param headers
* @param bodyParams
* @return
*/
public Request buildRequest(String url, Map<String, String> headers, Map<String, String> bodyParams) {
//1构造RequestBody
RequestBody body = setRequestBody(bodyParams);
Request.Builder builder = getRequestBuilder(headers);
//2 构造Request
Request request = builder.url(url).post(body).build();
return request;
}
/**
* post的请求参数,构造RequestBody
*
* @param bodyParams
* @return
*/
private RequestBody setRequestBody(Map<String, String> bodyParams) {
RequestBody body = null;
okhttp3.FormBody.Builder formBuilder = new okhttp3.FormBody.Builder();
if (bodyParams != null) {
for (Map.Entry<String, String> item : bodyParams.entrySet()) {
formBuilder.add(item.getKey(), item.getValue());
}
}
body = formBuilder.build();
return body;
}
}