Retrofit2.0带你装逼,带你飞

Retrofit2.0上手操作

  • retrofit简介
  • retrofit使用

retrofit简介

Retrofit是一款基于OKHttp的restful的网络请求框架。支持异步和同步请求,看到异步有么有两眼放光,服务器开发者可能会吐槽说:view层和后端服务之间通过ajax异步请求,你这异步有nuan用? 咳咳!Android用啊!大家可以看到很多入门教程都是针对android。但是,但是retrofit实在是太好用了,而且你怎么确定你一定不会用到异步的应用场景(当然你可以自己写线程)。retrofit通过接口注解,扩展性非常好,支持多种数据格式json,xml,string,protobuf,以及基于okhttp哦!赶紧抛弃你的httpclinet,来拥抱retrofit。

这里不做概念及入门介绍,完全陌生的请看官方文档。

retrofit使用

下面的样例来让你快速使用在自己的项目中而不是学习。下面的样例只讲,get,post/json,看完该样例,对于什么上传文件,form表单等绝对的轻车熟路。

项目使用meavn进行管理,引入retrofit2.0,及okhttp3.0

   <dependency>
    <groupId>com.squareup.retrofit2</groupId>
    <artifactId>retrofit</artifactId>
    <version>2.0.2</version>
   </dependency>
    <dependency>
    <groupId>com.squareup.retrofit2</groupId>
    <artifactId>converter-gson</artifactId>
    <version>2.0.2</version>
</dependency>
    <dependency>
    <groupId>com.squareup.retrofit2</groupId>
    <artifactId>converter-scalars</artifactId>
    <version>2.0.2</version>
</dependency>
    <dependency>
    <groupId>com.squareup.retrofit2</groupId>
    <artifactId>converter-simplexml</artifactId>
    <version>2.0.2</version>
</dependency>
    <dependency>
    <groupId>com.squareup.okhttp3</groupId>
    <artifactId>logging-interceptor</artifactId>
    <version>3.2.0</version>
</dependency>

老生常谈,retrofit依然是使用动态代理,只需要实现接口,仅此而已。业务分层,代码扩展性好。

package com.ccycc.retrofit.network.infs;

import com.ccycc.retrofit.vo.ReqVo;
import com.ccycc.retrofit.vo.RespVo;

import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Body;
import retrofit2.http.GET;
import retrofit2.http.Headers;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.Query;

public interface TestService {

    // 接口1
    @GET("ccycc88/article/details/79759172")
    Call<String> getCsdn();

    //接口2
    @GET("ccycc88/article/details/{userID}")
    Call<String> getCsdn(@Path(value = "userID") String id);

    //接口3
    @GET("ccycc88/article/details/79759172")
    Call<ResponseBody> getCsdnBody();

    //接口4
    @POST("admin/v1/transformIncomeDetail")
    Call<RespVo> postJson(@Body ReqVo vo);

    //接口5
    @GET("cgi-bin/token?grant_type=client_credential")
    Call<String> getAccessToken(@Query("appid") String appid, @Query("secret") String secret);

    //接口6
    @Headers({"Content-Type: application/json","Accept: application/json"})
    @POST("cgi-bin/message/custom/send")
    Call<ResponseBody> sendMessage(@Query("access_token") String accessToken, @Body RequestBody body);
}

无聊,因此为每个接口起了别名。
接口中@Path什么时候用? 如接口2,请求地址为:…/ccycc88/article/details/{userID} == …/ccycc88/article/details/123
接口中@Query什么时候用? 如接口5, 请求地址为: …/cgi-bin/token?grant_type=client_credential == cgi-bin/token?grant_type=client_credential&appid=appid&secret=secret。
@Path用于请求地址中的一部分,@Query用于请求参数。

为什么会有接口1样例?因为苦苦找了好久都没找到如何返回字符串样例。
于是为大家提供两种返回字符串的两种方式如:接口1接口3

咳!那最最最最最常用的restful风格呢?
接口4接口6

package com.ccycc.retrofit.vo;
/**
*请求对象
*/
public class ReqVo {

    private int pageNum = -1;

    private int displayNum = -1;

    public int getPageNum() {
        return pageNum;
    }

    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }

    public int getDisplayNum() {
        return displayNum;
    }

    public void setDisplayNum(int displayNum) {
        this.displayNum = displayNum;
    }   
}
package com.ccycc.retrofit.vo;

import java.util.List;
//响应对象
public class RespVo {

    private int errorCode = -1;

    private String errorMsg = null;

    private Data data = null;

    public int getErrorCode() {
        return errorCode;
    }

    public void setErrorCode(int errorCode) {
        this.errorCode = errorCode;
    }

    public String getErrorMsg() {
        return errorMsg;
    }

    public void setErrorMsg(String errorMsg) {
        this.errorMsg = errorMsg;
    }

    public Data getData() {
        return data;
    }

    public void setData(Data data) {
        this.data = data;
    }

    public class Data{

        int totalNum = -1;

        List<Row> rows = null;


        public int getTotalNum() {
            return totalNum;
        }


        public void setTotalNum(int totalNum) {
            this.totalNum = totalNum;
        }


        public List<Row> getRows() {
            return rows;
        }


        public void setRows(List<Row> rows) {
            this.rows = rows;
        }


        public class Row{

            String balanceType = null;
            long memberId = -1l;
            String model = null;
            int perIncome = -1;
            String transferId = null;
            String transferTime = null;
            String username = null;
            public String getBalanceType() {
                return balanceType;
            }
            public void setBalanceType(String balanceType) {
                this.balanceType = balanceType;
            }
            public long getMemberId() {
                return memberId;
            }
            public void setMemberId(long memberId) {
                this.memberId = memberId;
            }
            public String getModel() {
                return model;
            }
            public void setModel(String model) {
                this.model = model;
            }
            public int getPerIncome() {
                return perIncome;
            }
            public void setPerIncome(int perIncome) {
                this.perIncome = perIncome;
            }
            public String getTransferId() {
                return transferId;
            }
            public void setTransferId(String transferId) {
                this.transferId = transferId;
            }
            public String getTransferTime() {
                return transferTime;
            }
            public void setTransferTime(String transferTime) {
                this.transferTime = transferTime;
            }
            public String getUsername() {
                return username;
            }
            public void setUsername(String username) {
                this.username = username;
            }



        }
    }
}

//请求参数
{
   "pageNum":1,
   "displayNum":1
}
//响应结果
{
    "data": {
        "rows": [
            {
                "balanceType": "换机事件",
                "memberId": 10134,
                "model": "2014812",
                "perIncome": 1,
                "transferId": "152213107396210134866042021636589",
                "transferTime": "2018-03-27 14:27:54",
                "username": "凡安才"
            }
        ],
        "totalNum": 8
    },
    "errorCode": 0,
    "errorMsg": ""
}

上面的例子看到接口4实际是将请求的转换为ReqVo对象,将结果转换为RespVo对象。
接口6中实际是直接设定好请求体(body)。为什么会这样写呢?心酸啊!想到前一阵做微信公共号开发,微信的响应正常和异常返回的结果各种五花八门,我有心定义对象,有时间吗?说到微信公共号,不得不赞的是公共号自身的安全机制,非常好,现在公司都向公共号的这种安全处理靠拢,后期详细介绍。

下面看看这些接口是如何被调用。

package com.ccycc.retrofit;

import java.io.IOException;

import com.ccycc.retrofit.network.infs.TestService;
import com.ccycc.retrofit.vo.ReqVo;
import com.ccycc.retrofit.vo.RespVo;

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
import retrofit2.converter.scalars.ScalarsConverterFactory;

/**
 * Hello world!
 *
 */
public class App 
{
    //private String url = "https://blog.csdn.net/";

    private String url = "http://pcadmin.51kuaihj.com/";

    public static void main( String[] args )
    {
        App app = new App();
        //app.retrofitStringASync();

        //app.retrofitStringTwice();
        //app.retrofitStringBody();
        app.retrofitRest();
    }
    /**
     * 同步请求
     * 响应String 结果
     */
    public void retrofitStringSync() {

        //设置数据格式的转换工厂为ScalarsConverterFactory 及可返回字符串数据
        Retrofit retrofit = new Retrofit.Builder().client(new OkHttpClient()).baseUrl(url)
                .addConverterFactory(ScalarsConverterFactory.create()).build();

        //动态代理生成代理对象 test
        TestService test = retrofit.create(TestService.class);

        Call<String> call = test.getCsdn();

        //同步请求 execute
        try {
            Response<String> response = call.execute();
            String body = response.body();
            System.out.println(body);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /**
     * 异步请求
     * 响应String
     */
    public void retrofitStringASync() {

        Retrofit retrofit = new Retrofit.Builder().client(new OkHttpClient()).baseUrl(url)
                .addConverterFactory(ScalarsConverterFactory.create()).build();

        //动态代理生成代理对象 test
        TestService test = retrofit.create(TestService.class);

        Call<String> call = test.getCsdn();

        //异步请求
        call.enqueue(new Callback<String>() {

            public void onResponse(Call<String> call, Response<String> response) {
                // TODO Auto-generated method stub
                String body = response.body();
                System.out.println(body);
            }

            public void onFailure(Call<String> call, Throwable t) {
                // TODO Auto-generated method stub

            }
        });
    }

    public void retrofitStringCommonArgs() {

        Retrofit retrofit = new Retrofit.Builder().client(new OkHttpClient()).baseUrl(url)
                .addConverterFactory(ScalarsConverterFactory.create()).build();

        //动态代理生成代理对象 test
        TestService test = retrofit.create(TestService.class);

        //通过参数请求
        Call<String> call = test.getCsdn("79759172");

        //同步请求
        try {
            Response<String> response = call.execute();
            String body = response.body();
            System.out.println(body);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    /**
    *多次请求
    */
    public void retrofitStringTwice() {

        Retrofit retrofit = new Retrofit.Builder().client(new OkHttpClient()).baseUrl(url)
                .addConverterFactory(ScalarsConverterFactory.create()).build();

        //动态代理生成代理对象 test
        TestService test = retrofit.create(TestService.class);

        Call<String> call = test.getCsdn();
        //如果需要多次请求,必须要clone 一新对象
        Call<String> call2 = call.clone();
        //同步请求
        try {
            Response<String> response = call.execute();
            String body = response.body();
            //System.out.println(body);

            System.out.println("-------------------------------------");


            System.out.println(call2.execute().body());


        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void retrofitStringBody() {

        Retrofit retrofit = new Retrofit.Builder().client(new OkHttpClient()).baseUrl(url)
                .build();

        //动态代理生成代理对象 test
        TestService test = retrofit.create(TestService.class);

        Call<ResponseBody> call = test.getCsdnBody();

        //同步请求
        try {
            //这里通过返回 okhttp.responebody来获取响应体中的内容
            Response<ResponseBody> response = call.execute();
            String body = response.body().string();
            System.out.println(body);


        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

    public void retrofitRest() {

        //restful风格/json,需要转换工厂GsonConverterFactory
        Retrofit retrofit = new Retrofit.Builder().client(new OkHttpClient()).baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create()).build();

        //动态代理生成代理对象 test
        TestService test = retrofit.create(TestService.class);

        ReqVo vo = new ReqVo();
        vo.setDisplayNum(1);
        vo.setPageNum(1);
        Call<RespVo> call = test.postJson(vo);

        //同步请求
        try {
            Response<RespVo> response = call.execute();
            RespVo vo2 = response.body();
            System.out.println(vo2.getData().getRows().get(0).getBalanceType());


        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
    public void retrofitRestBody() {

        Retrofit retrofit = new Retrofit.Builder().client(new OkHttpClient()).baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create()).build();

        //动态代理生成代理对象 test
        TestService test = retrofit.create(TestService.class);

        String json ="{\r\n" + 
                "   \"pageNum\":1,\r\n" + 
                "   \"displayNum\":1\r\n" + 
                "}";
                //将json串直接放入请求体中
        RequestBody body = RequestBody.create(MediaType.parse("application/json"), json);
        Call<ResponseBody> call = test.sendMessage("12345", body);

        //同步请求
        try {
            Response<ResponseBody> response = call.execute();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}

小结

retrofit 很简单,是不是可以带你装逼,带你飞。关于https,代理了,添加证书了等问题,仅仅需要修改一下okhttp仅此而已,后面介绍。理解了上面的代码,哪些表单了,文件上传了还有何难度?
在这个json + restful横流的世界,是时候用retrofit了。

扫描二维码关注公众号,回复: 3399855 查看本文章

这里写图片描述

猜你喜欢

转载自blog.csdn.net/ccycc88/article/details/79885334
今日推荐