一 简介:
目前网上提供很多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; }