http框架--基于OkHttp 4 封装的http请求工具类
2023-09-11 14:16:24 时间
1. 基本介绍
OkHttp 是 Square 公司开源的一款网络框架,封装了一个高性能的 http 请求库。
支持 spdy、http2.0、websocket 等协议; 支持同步、异步请求; 封装了线程池,封装了数据转换,提高性能。
OkHttp算是最火的Http第三方库,Retrofit底层也是使用OkHttp
本文以okhttp 4.x版本,将OkHttp请求的相同代码进行封装,简化代码,便捷使用。
2. 工具类源代码
2.1 使用示例
以第三方系统集成海豚调度系统为例,演示http请求工具类的使用
工具类支持http、https协议,以链式进行调用,使用起来非常便捷。
class OkHttpUtilsTest {
public static void main(String[] args) {
String res = "";
// post请求,方法顺序按照这种方式,切记选择post/get一定要放在倒数第二,同步或者异步倒数第一,才会正确执行
res = OkHttpUtils.builder().url("http://172.25.xx.xx:12345/dolphinscheduler/login")
// 有参数的话添加参数,可多个
.addParam("userName", "admin")
.addParam("userPassword", "dolphinscheduler123")
.addHeader("Content-Type", "application/json; charset=utf-8")
.post(false)
.sync();
printMsg("login res:%s", res);
//ost请求,分为两种,一种是普通表单提交,一种是json提交
res = OkHttpUtils.builder().url("http://172.25.xx.xx:12345/dolphinscheduler/signOut")
.addHeader("Content-Type", "application/json; charset=utf-8")
.addHeader("token", "ca3e91749eee187fa9a797d92cf5cb6d")
.post(false)
.sync();
printMsg("signOut res:%s", res);
//get请求
res = OkHttpUtils.builder().url("http://172.25.xx.xx:12345/dolphinscheduler/log/detail")
// 有参数的话添加参数,可多个
.addParam("taskInstanceId", "709")
.addParam("skipLineNum", "0")
.addParam("limit", "1000")
.addHeader("Content-Type", "application/json; charset=utf-8")
.addHeader("token", "ca3e91749eee187fa9a797d92cf5cb6d")
.get()
.sync();
printMsg("log detail res:%s", res);
// 选择异步有两个方法,一个是带回调接口,一个是直接返回结果
res = OkHttpUtils.builder().url("http://172.25.xx.xx:12345/dolphinscheduler/log/detail")
.addParam("taskInstanceId", "709")
.addParam("skipLineNum", "0")
.addParam("limit", "1000")
.addHeader("Content-Type", "application/json; charset=utf-8")
.addHeader("token", "ca3e91749eee187fa9a797d92cf5cb6d")
.get()
.async();
printMsg("log detail res:%s", res);
OkHttpUtils.builder().url("http://172.25.xx.xx:12345/dolphinscheduler/log/detail")
.addParam("taskInstanceId", "709")
.addParam("skipLineNum", "0")
.addParam("limit", "1000")
.addHeader("Content-Type", "application/json; charset=utf-8")
.addHeader("token","ca3e91749eee187fa9a797d92cf5cb6d")
.get()
.async(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
printMsg("请求出错:%s", e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
assert response.body() != null;
printMsg("res:%s", response.body().string());
}
});
}
private static void printMsg(String template, Object... args) {
System.out.println(String.format(template, args));
}
}
2.2. maven依赖
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.1</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.5</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>28.0-jre</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.76</version>
</dependency>
2.3. 工具类源代码
import com.alibaba.fastjson.JSON;
import okhttp3.*;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.IOException;
import java.net.URLEncoder;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;
class OkHttpUtils {
private static volatile OkHttpClient okHttpClient = null;
//用于异步请求时,控制访问线程数,返回结果,设置为0表示只能1个线程同时访问,用于async()方法调用
private static volatile Semaphore semaphore = new Semaphore(0);
private Map<String, String> headerMap;
private Map<String, String> paramMap;
private String url;
private Request.Builder request;
/**
* 初始化okHttpClient,并且允许https访问
*/
private OkHttpUtils() {
if (okHttpClient == null) {
synchronized (OkHttpUtils.class) {
if (okHttpClient == null) {
TrustManager[] trustManagers = buildTrustManagers();
okHttpClient = new OkHttpClient.Builder()
.connectTimeout(15, TimeUnit.SECONDS)
.writeTimeout(20, TimeUnit.SECONDS)
.readTimeout(20, TimeUnit.SECONDS)
.sslSocketFactory(createSSLSocketFactory(trustManagers), (X509TrustManager) trustManagers[0])
.hostnameVerifier((hostName, session) -> true)
.retryOnConnectionFailure(true)
.connectionPool(new ConnectionPool(10,10,TimeUnit.SECONDS))
.build();
addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.77 Safari/537.36");
}
}
}
}
/**
* 创建OkHttpUtils
*
* @return
*/
public static OkHttpUtils builder() {
return new OkHttpUtils();
}
/**
* 添加url
*
* @param url
* @return
*/
public OkHttpUtils url(String url) {
this.url = url;
return this;
}
/**
* 添加参数
*
* @param key 参数名
* @param value 参数值
* @return
*/
public OkHttpUtils addParam(String key, String value) {
if (paramMap == null) {
paramMap = new LinkedHashMap<>(16);
}
paramMap.put(key, value);
return this;
}
/**
* 添加请求头
*
* @param key 参数名
* @param value 参数值
* @return
*/
public OkHttpUtils addHeader(String key, String value) {
if (headerMap == null) {
headerMap = new LinkedHashMap<>(16);
}
headerMap.put(key, value);
return this;
}
/**
* 初始化get方法
*
* @return
*/
public OkHttpUtils get() {
request = new Request.Builder().get();
StringBuilder urlBuilder = new StringBuilder(url);
if (paramMap != null) {
urlBuilder.append("?");
try {
for (Map.Entry<String, String> entry : paramMap.entrySet()) {
urlBuilder.append(URLEncoder.encode(entry.getKey(), "utf-8")).
append("=").
append(URLEncoder.encode(entry.getValue(), "utf-8")).
append("&");
}
} catch (Exception e) {
e.printStackTrace();
}
urlBuilder.deleteCharAt(urlBuilder.length() - 1);
}
request.url(urlBuilder.toString());
return this;
}
/**
* 初始化post方法
*
* @param isJsonPost true等于json的方式提交数据,类似postman里post方法的raw
* false等于普通的表单提交
* @return
*/
public OkHttpUtils post(boolean isJsonPost) {
RequestBody requestBody;
if (isJsonPost) {
String json = "";
if (paramMap != null) {
json = JSON.toJSONString(paramMap);
}
requestBody = RequestBody.create(json, MediaType.parse("application/json; charset=utf-8"));
} else {
FormBody.Builder formBody = new FormBody.Builder();
if (paramMap != null) {
paramMap.forEach(formBody::add);
}
requestBody = formBody.build();
}
request = new Request.Builder().post(requestBody).url(url);
return this;
}
/**
* 同步请求
*
* @return
*/
public String sync() {
setHeader(request);
try {
Response response = okHttpClient.newCall(request.build()).execute();
assert response.body() != null;
return response.body().string();
} catch (IOException e) {
e.printStackTrace();
return "请求失败:" + e.getMessage();
}
}
/**
* 异步请求,有返回值,因为使用锁,相当于同步请求
*/
public String async() {
StringBuilder buffer = new StringBuilder("");
setHeader(request);
okHttpClient.newCall(request.build()).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
semaphore.release();
buffer.append("请求出错:").append(e.getMessage());
}
@Override
public void onResponse(Call call, Response response) throws IOException {
semaphore.release();
assert response.body() != null;
buffer.append(response.body().string());
}
});
try {
semaphore.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
return buffer.toString();
}
/**
* 异步请求,带有接口回调
*
* @param callback
*/
public void async(Callback callback) {
setHeader(request);
okHttpClient.newCall(request.build()).enqueue(callback);
}
/**
* 为request添加请求头
*
* @param request
*/
private void setHeader(Request.Builder request) {
if (headerMap != null) {
try {
for (Map.Entry<String, String> entry : headerMap.entrySet()) {
request.addHeader(entry.getKey(), entry.getValue());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
/**
* 生成安全套接字工厂,用于https请求的证书跳过
*
* @return
*/
private static SSLSocketFactory createSSLSocketFactory(TrustManager[] trustAllCerts) {
SSLSocketFactory ssfFactory = null;
try {
SSLContext sc = SSLContext.getInstance("SSL");
sc.init(null, trustAllCerts, new SecureRandom());
ssfFactory = sc.getSocketFactory();
} catch (Exception e) {
e.printStackTrace();
}
return ssfFactory;
}
private static TrustManager[] buildTrustManagers() {
return new TrustManager[]{
new X509TrustManager() {
@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}
}
};
}
/**
* 自定义一个接口回调
*/
public interface ICallBack {
void onSuccessful(Call call, String data);
void onFailure(Call call, String errorMsg);
}
}
相关文章
- 【C#】工具类-FTP操作封装类FTPHelper
- 第一百六十节,封装库--JavaScript,ajax注册表单到数据库
- 对adapter的封装优化
- Robot Framework封装的关键字输入参数可以传入多个值的方法
- 声纹可视化工具:wavesurfer.js---在Vue中使用音频声纹可视化插件wavesurfer.js【已封装成组件有完整demo实例附完整代码】
- flutter 封装工具类
- Dataset之图片数据增强:设计自动生成(高级封装之命令行解析实现)汽车车牌图片算法(cv2+PIL+argparse)根据随机指定七个字符生成逼真车牌图片(自然场景+各噪效果+对应txt说明文档)
- DL之DNN:自定义2层神经网络TwoLayerNet模型(封装为层级结构)利用MNIST数据集进行训练、GC对比
- m基于光纤光栅传感网接入GPON的光纤通信系统matlab性能仿真,包括解码,解封装,分接,码率恢复,解帧,拆包,译码
- jsonp promise 封装
- spdlog单例模式封装
- css工具类封装
- js工具类的封装
- 华为桌面云封装Windows10系统出现sysprep无法验证您的Windows安装问题,完美解决