一 简介:

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