Gradle项目retrofit2+okhttp3实现http请求
一 简介:
目前网上提供很多Java实现httpServer封装,其中完善的就属hutools工具和本文介绍的。至于hutools工具中HttpUtils方法,大家可以根据API文档进行使用,比较快捷,hutools官方给的案例,各位只要按葫芦画瓢基本可以实现。既然有这么好的工具为啥我不用,转而研究retrofit2呢,因为异步和同步的问题。做过安卓开发的大佬,都会发现,安卓和java的区别安卓有自己的主线程,如果在安卓使用同步请求的话,主线程或被破坏,从而出现异常,我用retrofit2起因也是因为这个。
二 导入依赖
其实Gradle和Maven差不多,Maven库也有gradle导出的模板。
Maven库:https://mvnrepository.com
//OK包,这里是两种包,最好用我的,不然会有意想不到的惊喜,这都是大佬们总结出来的
compile 'com.squareup.okhttp3:okhttp:4.7.2'
compile 'com.squareup.okio:okio:2.6.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.0.2'
compile 'com.squareup.retrofit2:converter-gson:2.0.2'三 POST,GET,PUT,DELETE-restful接口四种常用请求方式
定一个接口类
1 POST请求方式
(1) application/json
@Headers({"Content-Type: application/json;charset=UTF-8"})
@POST(url)
Call<String> object(@Body RequestBody requestBody);实现类
public void object_bh_1(ReObject resquest){
Retrofit retrofit = new Retrofit.Builder()
//设置数据解析器
//.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(new ToStringConverterFactory())
.client(GetOkHttp())
//.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//设置网络请求的Url地址
// POST里面的url通常都是我们的路径和端口
.baseUrl(Global.UrlPrefix_bh)
.build();
//API 就是那个接口类
API api = retrofit.create(API.class);
Rpt.RptLog("[<对象接口 1> 创建对象-请求参数]:" + resquest.toString());
//这是自己封装一个类转JSON,JSON转类的方法
String json = JsonHelper.ToJson(resquest);
//这里是将json字符串转译成RequestBody
RequestBody requestBody =RequestBody.create(MediaType.parse("application/json; charset=utf-8"),json);
Call<String> all = api.object(requestBody);
Rpt.RptLog("[URL]"+all.request().url().toString());
Rpt.RptLog("[请求方式]"+all.request().method());
Rpt.RptLog("[HTTPS]"+all.request().isHttps());
Rpt.RptLog("------------------------------------------------");
all.enqueue(new Callback<String>() {
//请求成功时回调
@Override
public void onResponse(Call<String> call, Response<String> response) {
//这里是我自己设用一个实体类去转译返回的json字符串
ResObject retjson = null;
try {
retjson = (ResObject) JsonHelper.FromJson(response.body(),ResObject.class);
System.out.println(retjson);
}
catch (Exception e){
//这是自己封装输出打印日志的方法,可以自己更改
Rpt.RptLog("对象解析JSON错误信息:" + exceptionToString);
}
Rpt.RptLog("BH [<对象接口 1> 创建对象-返回参数] recv 1 : " + retjson.toString());
}
@Override
public void onFailure(Call<String> call, Throwable t) {
//请求失败时候的回调
String exceptionToString = ComFun.getExceptionToString(t);
Rpt.RptLog("BH [<对象接口 1> 创建对象-异常信息]:");
Rpt.RptLog(exceptionToString);
}
});
}(2) multipart/form-data
@Multipart
@POST(url)
Call<String> check(@PartMap Map<String, RequestBody> requestBodyMap);实体类
public void check_bh(ReCheck resquest)throws Exception{
Retrofit retrofit = new Retrofit.Builder()
//设置数据解析器
//.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(new ToStringConverterFactory())
.client(GetOkHttp())
//.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//设置网络请求的Url地址
.baseUrl(Global.UrlCheck_bh)
.build();
API_num bh = retrofit.create(API_num.class);
Rpt.RptLog("[<设备接口 明文 1> Imsi与phone互查接口-请求参数]:" + resquest.toString());
String body = resquest.body;
//这里涉及nopading-AES加密
AESencrp aeSencrp = new AESencrp(Global.KEY);
String encry = aeSencrp.encrypt(body);
resquest.body=encry;
String json = JsonHelper.ToJson(resquest);
Rpt.RptLog("[<设备接口 密文 1> Imsi与phone互查接口-请求参数]:" + resquest.toString());
Rpt.RptLog("[<设备接口 密文 1> Imsi与phone互查接口-请求参数]:" + json);
Map<String, String> requestDataMap = new HashMap<>();
requestDataMap.put("account",resquest.account);
requestDataMap.put("body",resquest.body);
//这异步也是转译
Map<String, RequestBody> RequestBodyMap = generateRequestBody(requestDataMap);
Call<String> all = bh.check(RequestBodyMap);
Rpt.RptLog("[URL]"+all.request().url().toString());
Rpt.RptLog("请求方式:"+all.request().method());
Rpt.RptLog("是否HTTPS请求:"+all.request().isHttps());
Rpt.RptLog("------------------------------------------------");
all.enqueue(new Callback<String>() {
//请求成功时回调
@Override
public void onResponse(Call<String> call, Response<String> response) {
ResCheck retjson = null;
try {
retjson = (ResCheck)JsonHelper.FromJson(response.body(),ResCheck.class);
retjson.body = aeSencrp.decrypt(retjson.body);
retjson.result = aeSencrp.decrypt(retjson.result);
String s = retjson.result;
s = s.substring(s.indexOf("[")+2,s.lastIndexOf("]")-1);
}
catch (Exception e){
String exceptionToString = ComFun.getExceptionToString(e);
Rpt.RptLog("对象解析JSON错误信息:" + exceptionToString);
}
Rpt.RptLog("BH [<设备接口 明文 1> Imsi与phone互查接口-返回参数] recv 1 : " + retjson.toString());
}
@Override
public void onFailure(Call<String> call, Throwable t) {
//请求失败时候的回调
Rpt.RptLog("BH [<设备接口 1> Imsi与phone互查接口-异常信息]:");
String exceptionToString = ComFun.getExceptionToString(t);
Rpt.RptLog(exceptionToString);
}
});
}
/*
* @Author 吕习伟
* @Date 14:30 2020/6/20
* @Param
* @return
* @Description formdata 数据格式转换
**/
public static Map<String, RequestBody> generateRequestBody(Map<String, String> requestDataMap) {
Map<String, RequestBody> requestBodyMap = new HashMap<>();
for (String key : requestDataMap.keySet()) {
RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"),
requestDataMap.get(key) == null ? "" : requestDataMap.get(key));
requestBodyMap.put(key, requestBody);
}
return requestBodyMap;
}2 GET请求方式 因为GET属于URL拼接,url?p=1&p2=2&p3=3;
@GET(url)
Call<String> task(@Query("param1") String param1,
@Query("param2") int param2,
@Query("param3") String param3);实体类
public void task_bh(ReTask resquest){
//OkHttpClient.Builder okhttpClient = GetOkHttp();
Retrofit retrofit = new Retrofit.Builder()
//设置数据解析器
//.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(new ToStringConverterFactory())
.client(GetOkHttp())
//.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//设置网络请求的Url地址
.baseUrl(Global.UrlPrefix_bh)
.build();
API_bh bh = retrofit.create(API_bh.class);
Rpt.RptLog("[<设备接口 1> 监控任务-请求参数]:" + resquest.toString());
Call<String> all = bh.task(resquest.getSerial_num(),resquest.getSize(),resquest.getDev_version());
Rpt.RptLog("[URL]"+all.request().url().toString());
Rpt.RptLog("请求方式:"+all.request().method());
Rpt.RptLog("是否HTTPS请求:"+all.request().isHttps());
Rpt.RptLog("------------------------------------------------");
all.enqueue(new Callback<String>() {
//请求成功时回调
@Override
public void onResponse(Call<String> call, Response<String> response) {
//Rpt.RptLog("BH Task recv 0 : " + response.body());
//System.out.println(response.body());
ResTask retjson = null;
try {
retjson = (ResTask)JsonHelper.FromJson(response.body(),ResTask.class);
}
catch (Exception e){
String exceptionToString = ComFun.getExceptionToString(e);
Rpt.RptLog("对象解析JSON错误信息:" + exceptionToString);
}
Rpt.RptLog("BH [<设备接口 1> 监控任务-返回参数] recv 1 : " + retjson.toString());
//Rpt.RptLog("Register recv: " + retjson);
//System.out.println(retjson);
Global.devRegAckDeal.Deal_bh_Reg(retjson);
}
@Override
public void onFailure(Call<String> call, Throwable t) {
//请求失败时候的回调
Rpt.RptLog("BH [<设备接口 1> 监控任务-异常信息]:");
String exceptionToString = ComFun.getExceptionToString(t);
Rpt.RptLog(exceptionToString);
}
});
}3 PUT
(1) application/json
@Headers({"Content-Type: application/json;charset=UTF-8"})
@POST("manufactor/task")
Call<String> task_obj(@Body RequestBody requestBody);实体类
public void task_obj_bh_4(ReObjTask resquest){
Retrofit retrofit = new Retrofit.Builder()
//设置数据解析器
//.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(new ToStringConverterFactory())
.client(GetOkHttp())
//.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//设置网络请求的Url地址
.baseUrl(Global.UrlPrefix_bh)
.build();
API_bh_obj bh = retrofit.create(API_bh_obj.class);
Rpt.RptLog("[<对象接口 4> 对象任务添加-请求参数]:" + resquest.toString());
String json = JsonHelper.ToJson(resquest);
RequestBody requestBody =RequestBody.create(MediaType.parse("application/json; charset=utf-8"),json);
Call<String> all = bh.task_obj(requestBody);
Rpt.RptLog("[URL]"+all.request().url().toString());
Rpt.RptLog("[请求方式]"+all.request().method());
Rpt.RptLog("[HTTPS]"+all.request().isHttps());
Rpt.RptLog("------------------------------------------------");
all.enqueue(new Callback<String>() {
//请求成功时回调
@Override
public void onResponse(Call<String> call, Response<String> response) {
ResObject retjson = null;
try {
retjson = (ResObject) JsonHelper.FromJson(response.body(),ResObject.class);
System.out.println(retjson);
}
catch (Exception e){
String exceptionToString = ComFun.getExceptionToString(e);
Rpt.RptLog("对象解析JSON错误信息:" + exceptionToString);
}
Rpt.RptLog("BH [<对象接口 4> 对象任务添加-返回参数] recv 1 : " + retjson.toString());
//Global.devRegAckDeal.Deal_bh_Reg(retjson);
}
@Override
public void onFailure(Call<String> call, Throwable t) {
//请求失败时候的回调
String exceptionToString = ComFun.getExceptionToString(t);
Rpt.RptLog("BH [<对象接口 4> 对象任务添加-异常信息]:");
Rpt.RptLog(exceptionToString);
}
});
}(2) 类似GET请求的URL拼接模式
@PUT("manufactor/start-monitor")
Call<String> start(@Query("object_id") String object_id);实体类
public void object_start_monitor_put_bh_8(String resquest){
Retrofit retrofit = new Retrofit.Builder()
//设置数据解析器
//.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(new ToStringConverterFactory())
.client(GetOkHttp())
//.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//设置网络请求的Url地址
.baseUrl(Global.UrlPrefix_bh)
.build();
API_bh_obj bh = retrofit.create(API_bh_obj.class);
Rpt.RptLog("[<对象接口 8> 对象开启管控-请求参数]:" + resquest);
Call<String> all = bh.start(resquest);
Rpt.RptLog("URL:"+all.request().url().toString());
Rpt.RptLog("请求方式:"+all.request().method());
Rpt.RptLog("是否HTTPS请求:"+all.request().isHttps());
Rpt.RptLog("------------------------------------------------");
all.enqueue(new Callback<String>() {
//请求成功时回调
@Override
public void onResponse(Call<String> call, Response<String> response) {
ResStartMonitor retjson = null;
try {
retjson = (ResStartMonitor) JsonHelper.FromJson(response.body(),ResStartMonitor.class);
System.out.println(retjson);
}
catch (Exception e){
String exceptionToString = ComFun.getExceptionToString(e);
Rpt.RptLog("对象解析JSON错误信息:" + exceptionToString);
}
Rpt.RptLog("BH [<对象接口 8> 对象开启管控-返回参数] recv 1 : " + retjson.toString());
//Global.devRegAckDeal.Deal_bh_Reg(retjson);
}
@Override
public void onFailure(Call<String> call, Throwable t) {
//请求失败时候的回调
String exceptionToString = ComFun.getExceptionToString(t);
Rpt.RptLog("BH [<对象接口 8> 对象开启管控-异常信息]:");
Rpt.RptLog(exceptionToString);
}
});
}4 DELETE
这种请求方式只介绍URL拼接模式的
@DELETE("manufactor/task")
Call<String> task_delete(@Query("task_id") String task_id,
@Query("app_id") String app_id);实体类
public void task_obj_delete_bh_5(String task_id,String app_id){
Retrofit retrofit = new Retrofit.Builder()
//设置数据解析器
//.addConverterFactory(GsonConverterFactory.create())
.addConverterFactory(new ToStringConverterFactory())
.client(GetOkHttp())
//.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
//设置网络请求的Url地址
.baseUrl(Global.UrlPrefix_bh)
.build();
API_bh_obj bh = retrofit.create(API_bh_obj.class);
Rpt.RptLog("[<对象接口 5> 对象任务删除]task_id[请求参数]:" + task_id+"");
Rpt.RptLog("[<对象接口 5> 对象任务删除]app_id[请求参数]:" + app_id+"");
Call<String> all = bh.task_delete(task_id,app_id);
Rpt.RptLog("[URL]"+all.request().url().toString());
Rpt.RptLog("[请求方式]"+all.request().method());
Rpt.RptLog("[HTTPS]"+all.request().isHttps());
Rpt.RptLog("------------------------------------------------");
all.enqueue(new Callback<String>() {
//请求成功时回调
@Override
public void onResponse(Call<String> call, Response<String> response) {
ResObjectPut retjson = null;
try {
retjson = (ResObjectPut) JsonHelper.FromJson(response.body(),ResObjectPut.class);
System.out.println(retjson);
}
catch (Exception e){
String exceptionToString = ComFun.getExceptionToString(e);
Rpt.RptLog("对象解析JSON错误信息:" + exceptionToString);
}
Rpt.RptLog("BH [<对象接口 5> 对象任务删除-返回参数] recv 1 : " + retjson.toString());
//Global.devRegAckDeal.Deal_bh_Reg(retjson);
}
@Override
public void onFailure(Call<String> call, Throwable t) {
//请求失败时候的回调
String exceptionToString = ComFun.getExceptionToString(t);
Rpt.RptLog("BH [<对象接口 5> 对象任务删除-异常信息]:");
Rpt.RptLog(exceptionToString);
}
});
}关于HTTP/HTTPS 问题解决
直接给代码,看不懂,搭配上面的方法可以使用
public OkHttpClient okhttpClient_global = null;
public OkHttpClient GetOkHttp(){
if(okhttpClient_global!=null){
return okhttpClient_global;
}
//首先创建OkHttpClient.build进行信任所有证书配置
// OkHttpClient.Builder okhttpClient = new OkHttpClient().newBuilder();
OkHttpClient.Builder okhttpClient = new OkHttpClient.Builder().
connectTimeout(60, TimeUnit.SECONDS).
readTimeout(60, TimeUnit.SECONDS).
writeTimeout(60, TimeUnit.SECONDS);
//信任所有服务器地址
okhttpClient.hostnameVerifier(new HostnameVerifier() {
@Override
public boolean verify(String s, SSLSession sslSession) {
//设置为true
return true;
}
});
//创建管理器
TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] x509Certificates,
String s) throws java.security.cert.CertificateException {
}
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] x509Certificates,
String s) throws java.security.cert.CertificateException {
}
@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[] {};
}
} };
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
//为OkHttpClient设置sslSocketFactory
okhttpClient.sslSocketFactory(sslContext.getSocketFactory());
} catch (Exception e) {
Rpt.RptLog("Init Okhttp出错");
String exceptionToString = ComFun.getExceptionToString(e);
System.out.println(exceptionToString);
Rpt.RptLog(exceptionToString);
e.printStackTrace();
}
okhttpClient_global = okhttpClient.build();
return okhttpClient_global;
}
查看4道真题和解析