Retrofit 菜鸟必入

来源:互联网 发布:c语言冒泡排序比较方法 编辑:程序博客网 时间:2024/05/21 09:49

一、添加依赖

在Module的build.gradle中添加如下依赖:

    //retrofit    compile 'com.squareup.retrofit2:retrofit:2.0.2'    //retrofit  String的转换器    compile 'com.squareup.retrofit2:converter-scalars:2.1.0'    //retrofit   Gson的转换器    compile 'com.squareup.retrofit2:converter-gson:2.1.0'    //retrofit    返回值的adapter的转化器,为了于RxJava配合使用    compile 'com.squareup.retrofit2:adapter-rxjava:2.3.0'

二、Get请求

我在这里只讲Get请求和Post请求,因为其他的请求没用过。

  • 1、首先我们将我们要访问的地址URL分成两个部分
如://我们要访问的地址http://www.xxx.com/api/rest/session//基地址http://www.xxx.com/api/rest///剩下的部分session

注意
retrofit2.0之后的baseUrl必需以/(斜线)结束,否则会报IllegalArgumentException异常

  • 2、创建接口并定义方法

说明: 看见Call是不是感觉眼熟,是不是想起了Okhttp3,retrofit默认返回的就是Call < ResponseBody>类型(okhttp3.ResponseBody这个包);至于怎么转变为想要的类型接下来慢慢说。

/** * * 注解说明: * * 标记: *  * 1、FormUrlEncoded 注解:表示请求体是一个Form表单; * * 2、Multipart 注解:表示请求体是一个支持文件上传的Form表单; * * 3、Streaming 注解:表示响应体的数据用流的形式返回,如果,没有用该注解,默认会吧数据存在内存,之后通过流读取数据也是读内存中的数据,如果数据比较大,建议使用该注解。 * * 参数: * * 1、Headers:用于添加请求头 * * 2、Header:用于添加不固定值的Header * * 3、Body:用于非表单请求体 * * 4、Field、FieldMap、Part、PartMap:用于表单字段 * *      Field、FieldMap与FormUrlEncoded配合使用; *      Part、PartMap与Multipart配合使用,适合有文件上传的情况; * *      FieldMap:接受的类型为Map<String,String>; *      PartMap默认接受的类型为Map<String,RequestBody>. * * 5、Path、Query、QueryMap、Url:用于URL * *      Query、QueryMap中的数据体现在URL上,Field、FieldMap的数据是请求体,但是两者生成的数据形式是一样的。 *  * @Get("")中一定要有参数,否则会报错 */public interface MyService {    @Headers("X-Oc-Merchant-Id:1qaz2wsx")    @GET("session")    Call<ResponseBody> getSessionResponseBody();    }
  • 3、使用接口

注意:回调是主线程、主线程、主线程

/**     * 在默认情况下Retrofit只支持将HTTP的响应体转换为ResponseBody     */    private void retrofitResponseBody() {        //得到retrofit,并设置相应的基地址,别忘了调用build()        Retrofit retrofit = new Retrofit.Builder()                .baseUrl("http://www.xxx.com/api/rest/")                .build();        //通过retrofit得到接口        MyService myService = retrofit.create(MyService.class);        //通过接口调用刚才定义的方法,看到了吧,这个返回值为call        Call<ResponseBody> call = myService.getSessionResponseBody();        //然后和okhttp一样调用enqueue,这个是异步,这里要注意哈,回调是主线程,和okhttp不一样,切记、切记、切记        call.enqueue(new Callback<ResponseBody>() {            @Override            public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {                try {                    Log.e("------------>", "response" + response.body().string());                } catch (IOException e) {                    e.printStackTrace();                }            }            @Override            public void onFailure(Call<ResponseBody> call, Throwable t) {            }        });    }

三、Get请求,使用Converter转换ResponseBody

---->转换为String,或者Gson解析的对象

我这里说的转换为String,不单单是String,而是Call< String>,转换为对象也是同理。这里需要引入一个新的东西Converter转换器,在添加依赖的时候应该看到了,有一个转为String的转换器的依赖,官方还提供了其他的几个,这里我只添加了String和Gson的。

  • 1、先看看接口
//我这个里面都添加了头,这个是我门接口的要求,可根据自己的需求添加purlic interface MyService{    @Headers("X-Oc-Merchant-Id:dsdsdsdsds")    @GET("session")    Call<String> getSession();    @GET("session")    @Headers("X-Oc-Merchant-Id:dsdsdsdsds")    Call<Session> getSessionGson();}
  • 2、使用

步骤还是上面的那些,这里我就简化了,一只.下去了(链式)

private void retrofitGet() {        Retrofit retrofit = new Retrofit.Builder()                .baseUrl("http://www.xxx.com/api/rest/")                .addConverterFactory(ScalarsConverterFactory.create())//增加返回值为String的支持                .addConverterFactory(GsonConverterFactory.create())//Gson转换器                .build();        //创建接口文件        MyService myService = retrofit.create(MyService.class);        //返回数据是String        myService.getSession().enqueue(new Callback<String>() {            @Override            public void onResponse(Call<String> call, Response<String> response) {                Log.e("----------->", "response" + response.body() + ",message:" + response.message() + "当前线程:" + Thread.currentThread().getName());            }            @Override            public void onFailure(Call<String> call, Throwable t) {            }        });        //返回的数据是Session类型        myService.getSessionGson().enqueue(new Callback<Session>() {            @Override            public void onResponse(Call<Session> call, Response<Session> response) {                Session session = response.body();                Log.e("------------->", "requestbody  session" + session.getData().getSession() + "success:" + response.body().getSuccess() + ",message:" + response.message());            }            @Override            public void onFailure(Call<Session> call, Throwable t) {            }        });    }
  • 3、说明:

这里可以看到我在创建retrofit的时候,不光添加了基地址还多了两行

//增加返回值为String的支持 .addConverterFactory(ScalarsConverterFactory.create()).addConverterFactory(GsonConverterFactory.create()) //Gson转换器 
  • 4、注意

如果返回的类型不是ResponseBody,还不加上面两句话,会报如下异常:

java.lang.IllegalArgumentException: Unable to create converter for class java.lang.String异常

四、GET请求,@Path和@Query

  • 1、接口

同样我都写在了MyService中

下面的两个URL为:

http://www.xxx.com/api/rest/products?id= 65http://www.xxx.com/api/rest/products/{product_id}//将product_id替换为65
    /**     * 会将id拼接在URL后面及?id=传进来的值     * @param id     * @return     */    @GET("products")    @Headers("X-Oc-Merchant-Id:1qaz2wsx")    Call<String> getProductDetial(@Query("id") String id);    /**     * 直接将路径中的进行替换,{xxxx}就相当于占位符,然后直接用参数替代就可以了     * @param product_id     * @return     */    @GET("products/{product_id}")    @Headers("X-Oc-Merchant-Id:1qaz2wsx")    Call<String> getProductDetialPath(@Path("product_id")String product_id);
  • 2、使用
/**     * 查询参数的设置     *      * 如果Query参数比较多,那么可以通过@QueryMap方式将所有的参数集成在一个Map统一传递     */    private void retrofitGetQuery() {        Retrofit retrofit = new Retrofit.Builder()                .baseUrl("http://www.xxx.com/api/rest/")                .addConverterFactory(ScalarsConverterFactory.create())                .build();        MyService myService = retrofit.create(MyService.class);        myService.getProductDetial("65").enqueue(new Callback<String>() {            @Override            public void onResponse(Call<String> call, Response<String> response) {                Log.e("------------>", "response" + response.body());            }            @Override            public void onFailure(Call<String> call, Throwable t) {                Log.e("------------>", "t" + t);            }        });    }    /**     * get请求     *      * 说明@Path和@Query的区别:     *      * 1、@Path:http://www.xxx.com/api/rest/products?id=65   ----->主要定位在路径上     *      * 2、@Query:http://www.xxx.com/api/rest/products/{product_id} (把{product_id}直接写成65) ------->主要定位在参数上     *      * {占位符}和PATH尽量只用在URL的path部分,url中的参数使用Query和QueryMap 代替     */    private void retrofitGetPath() {        Retrofit retrofit = new Retrofit.Builder()                .baseUrl("http://www.xxx.com/api/rest/")                .addConverterFactory(ScalarsConverterFactory.create())                .build();        MyService myService = retrofit.create(MyService.class);        myService.getProductDetialPath("65").enqueue(new Callback<String>() {            @Override            public void onResponse(Call<String> call, Response<String> response) {                Log.e("------------>", "response" + response.body());            }            @Override            public void onFailure(Call<String> call, Throwable t) {                Log.e("------------>", "t" + t);            }        });    }

五、Post请求参数为Json类型及使用@Body

  • 1、接口

上面也说过,非表单的参数使用@Body

请求头我们可以添加多个/**     * post请求参数类型是json     * @param requestBody     * @return     */    @POST("cart?from=cart")    @Headers({            "X-Oc-Merchant-Id:1qaz2wsx",            "X-OC-SESSION:8cn12jj6bruv5iemtuq0q43461",            "Content-Type:application/json"    })    Call<String> postBody(@Body RequestBody requestBody);
  • 2、使用
/**     * post请求,参数是json类型的时候     */    private void retrofitPostJson() {        Retrofit retrofit = new Retrofit.Builder()                .baseUrl("http://www.xxx.com/api/rest/")                .addConverterFactory(ScalarsConverterFactory.create())                .build();        MyService myService = retrofit.create(MyService.class);        Map<String, String> params = new HashMap<>();        params.put("product_id", "65");        params.put("quantity", "2");        params.put("option", "");        params.put("recurring_id", "0");        //使用Gson将map转为json字符串        String json = new Gson().toJson(params);        Log.e("------------>", "json" + json);        //使用okHttp中的MediaType创建RequestBody        myService.postBody(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), json)).enqueue(new Callback<String>() {            @Override            public void onResponse(Call<String> call, Response<String> response) {                Log.e("----------->", "responseffff" + response.body());            }            @Override            public void onFailure(Call<String> call, Throwable t) {            }        });    }
  • 3、说明

在学okHttp的时候我们可以将包含普通表单、json、以及包含文件的数据,放到RequestBody中当参数,所以这里也这么使用。也就明白,接口中的参数为啥为RequestBody类型了。

六、Post请求,参数为Map及使用@FieldMap

及post的请求参数是map类型

  • 1、接口

注意要加上@FormUrlEncoded标记

   /**     * post请求FormUrlEncoded和FieldMap配合使用     * @param id     * @param params     * @return     */    @FormUrlEncoded    @POST("healthplan/plans/{id}")    Call<String> postFieldMap(@Path("id") String id,@FieldMap Map<String,String> params);
  • 2、使用
 /**     * post请求使用@FieldMap,参数是Map类型的     */    private void retrofitPostFieldMap() {        Retrofit retrofit = new Retrofit.Builder()                .addConverterFactory(ScalarsConverterFactory.create())                .baseUrl("http://app.xxx.com/v1.0.0/")                .build();        Map<String, String> map = new HashMap<>();        map.put("nickName", "单线程");        map.put("reResourceUrl", "");        map.put("reResourceId", "");        retrofit.create(MyService.class).postFieldMap("169", map).enqueue(new Callback<String>() {            @Override            public void onResponse(Call<String> call, Response<String> response) {                Log.e("------------>", "response" + response.body());            }            @Override            public void onFailure(Call<String> call, Throwable t) {                Log.e("------------>", "t" + t);            }        });    }

你真的会用Retrofit2吗?Retrofit2完全教程

在添加转换器的时候是不是看到了一个和那个方法长得很像的方法,那个方法就可以让你和RxAndroid 一起使用了,继续往下看吧。

原创粉丝点击