Retrofit各种姿势请求

前言

本文是纯RetrofitDemo,和RxJava无关,如有错误请直接指出,感谢。

文档

GitHub:
https://github.com/square/retrofit

官方文档:
http://square.github.io/retrofit/

本文测试接口:

String URL = “https://api.douban.com/v2/movie/top250?start=0&count=10“; //豆瓣接口

引入

compile ‘com.squareup.retrofit2:retrofit:2.1.0’//retrofit依赖
compile ‘com.squareup.retrofit2:converter-scalars:2.1.0’//场景是这样,服务端返回一个不定类型的json数据,无法确定映射的Gson对象。
compile ‘com.squareup.retrofit2:converter-gson:2.1.0’//retrofit内部封装的GSON
compile ‘com.squareup.okhttp3:logging-interceptor:3.4.1’//log

注意加粗那个converter,converter有如下:

Gson: com.squareup.retrofit2:converter-gson 
Jackson: com.squareup.retrofit2:converter-jackson 
Moshi: com.squareup.retrofit2:converter-moshi 
Protobuf: com.squareup.retrofit2:converter-protobuf 
Wire: com.squareup.retrofit2:converter-wire 
Simple XML: com.squareup.retrofit2:converter-simplexml

Retrofit基础:

初始化Retrofit

//日志拦截器
HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor(new HttpLoggingInterceptor.Logger() {
            @Override
            public void log(String message) {
                //打印retrofit日志
                Log.i(TAG, "retrofitBack = " + message);
            }
        });

        loggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);

        OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(loggingInterceptor)
                //超时时间 不设置的话 默认30秒
//                .connectTimeout(mTimeOut, TimeUnit.SECONDS)
//                .readTimeout(mTimeOut, TimeUnit.SECONDS)
//                .writeTimeout(mTimeOut, TimeUnit.SECONDS)
                .build();

        Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(BASE_URL)//增加返回值为String的支持
                .client(client)//指定okHttpClient
                .addConverterFactory(ScalarsConverterFactory.create())//返回对象支持
                .addConverterFactory(GsonConverterFactory.create())//增加返回值为Gson的支持(返回实体类)
                .build();

初始化RequestApi,请求接口实例

//这里采用的是Java的动态代理模式,得到请求接口对象
final RequestApi PostApi = retrofit.create(RequestApi.class);

RequestApi.class

package zj.playretrofit;

import io.reactivex.Flowable;
import io.reactivex.Observable;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
import retrofit2.http.Path;
import retrofit2.http.Query;

public interface RequestApi {

    String URL = "https://api.douban.com/v2/movie/top250?start=0&count=10"; //豆瓣接口

    /**
     * 结合rxJava
     */
    @GET("{url}")
    Observable<ResponseData> getPathDoubadataRx(@Path("url") String url);

    @GET("v2/movie/top250")
    Observable<ResponseData> getDoubadata(@Query("start") String start, @Query("count") String count);

    @FormUrlEncoded
    @POST("v2/movie/top250")
    Flowable<ResponseData> postDoubanData(@Field("start") String start, @Field("count") String count);

}

执行请求接口

这里的ResponseBean是我根据豆瓣返回的字段用Bean生成工具生成的一个实体对象。
这里的Call/CallBack对象,看包名,是retrofit的。
import retrofit2.Call;
import retrofit2.Callback;
简单看下源码:

  • Call
    这个类是个interface,它的实现类是OkHttpCall,就是说这个对象是就是Retrofit封装OkHttp的关键对象,它就类似一个OkHttp的代理人,如下代码所示进行enqueue操作。

  • Callback
    这个就纯粹是一个回调用的接口实例了,没太大意义。

   /**
     * 执行并显示“请求接口”
     *
     * @param call
     */
    private void doCall(Call<ResponseBean> call) {
        //call#enqueue请求网络
        if (!call.isExecuted()) {
            call.enqueue(new Callback<ResponseBean>() {

                @Override
                public void onResponse(Call<ResponseBean> call, Response<ResponseBean> response) {
                    Log.d(TAG, response.body() == null ? "null" : response.body().toString());
                    PublicUtils.isMainThread();
                }

                @Override
                public void onFailure(Call<ResponseBean> call, Throwable t) {
                    Log.d(TAG, "失败" + t.toString());
                    PublicUtils.isMainThread();
                }
            });
        }
    }

Retrofit请求字段:

用于Http Get请求传递参数.如:

@Query、@QueryMap

@GET("group/users")
Call<List<User>> groupList(@Query("id") int groupId);

等同于:

@GET("group/users?id=groupId")

即将@Query的key-value添加到url后面组成get方式的参数,@QueryMap同理

@Field

用于Post方式传递参数,需要在请求接口方法上添加@FormUrlEncoded,即以表单的方式传递参数.示例:

@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);

@Path

用于URL上占位符.如:

@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);

将groupId变量的值替换到url上的id位置。

@Part

配合@Multipart使用,一般用于文件上传,看官方文档示例:

@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);

添加http header

@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)

等同于

@Headers("Authorization: authorization")//这里authorization就是上面方法里传进来变量的值
@GET("widget/list")
Call<User> getUser()

@Headers

跟@Header作用一样,只是使用方式不一样,@Header是作为请求方法的参数传入,@Headers是以固定方式直接添加到请求方法上.示例:

@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();

多个设置:

@Headers({
    "Accept: application/vnd.github.v3.full+json",
    "User-Agent: Retrofit-Sample-App"
})
@GET("widget/list")
Call<List<Widget>> widgetList();

验证以及log观察

运行本文的demo进行测试。本文主要进行了3种类型的请求测试。

1.Post请求:

        findViewById(R.id.btn_request_post).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d(TAG, "请求发起...post");
                doCall(PostApi.postDoubanData("0", "10"));//传入district的值,得到Call对象
            }
        });
    @FormUrlEncoded
    @POST("v2/movie/top250")
    Call<ResponseBean> postDoubanData(@Field("start") String start, @Field("count") String count);

Log观察

11-30 16:43:56.716 30840-30840/zj.playretrofit D/PlayReTro: 请求发起...post
11-30 16:43:56.719 30840-5491/zj.playretrofit I/PlayReTro: retrofitBack = --> POST https://api.douban.com/v2/movie/top250 http/1.1
......
11-30 16:43:56.720 30840-5491/zj.playretrofit I/PlayReTro: retrofitBack = start=0&count=10
11-30 16:43:56.720 30840-5491/zj.playretrofit I/PlayReTro: retrofitBack = --> END POST (16-byte body)
11-30 16:43:57.856 30840-5491/zj.playretrofit I/PlayReTro: retrofitBack = <-- 200 OK https://api.douban.com/v2/movie/top250 (1134ms)
......
11-30 16:43:57.868 30840-5491/zj.playretrofit I/PlayReTro: retrofitBack = {"count": 10, "start": 0, "total": 250, "subjec...}

2.Get请求:

        findViewById(R.id.btn_request_get).setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                Log.d(TAG, "请求发起...get & query");
                doCall(PostApi.getDoubadata("0", "10"));
            }
        });
    @GET("v2/movie/top250")
    Call<ResponseBean> getDoubadata(@Query("start") String start, @Query("count") String count);

Log观察

11-30 17:21:36.430 8857-8931/zj.playretrofit I/PlayReTro: retrofitBack = --> GET https://api.douban.com/v2/movie/top250?start=0&count=10 http/1.1
11-30 17:21:36.430 8857-8931/zj.playretrofit I/PlayReTro: retrofitBack = --> END GET
11-30 17:21:37.398 8857-8931/zj.playretrofit I/PlayReTro: retrofitBack = <-- 200 OK https://api.douban.com/v2/movie/top250?start=0&count=10 (967ms)
......
11-30 17:21:37.411 8857-8931/zj.playretrofit I/PlayReTro: retrofitBack = {"count": 10, "sta...}

3.GET以地址的方式请求:

        findViewById(R.id.btn_request_single_path).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Log.d(TAG, "请求发起...path");
                String url = "v2/book/1003078";
                doCall(PostApi.getPathDoubadata(url));
            }
        });
    @GET("{url}")
    Call<ResponseBean> getPathDoubadata(@Path("url") String url);

Log观察

11-30 17:27:39.305 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = --> GET https://api.douban.com/v2%2Fbook%2F1003078 http/1.1
11-30 17:27:39.305 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = --> END GET
11-30 17:27:39.454 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = <-- 200 OK https://api.douban.com/v2%2Fbook%2F1003078 (148ms)
11-30 17:27:39.454 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = Date: Thu, 30 Nov 2017 09:27:37 GMT
11-30 17:27:39.454 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = Content-Type: application/json; charset=utf-8
11-30 17:27:39.454 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = Transfer-Encoding: chunked
11-30 17:27:39.454 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = Connection: keep-alive
11-30 17:27:39.454 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = Keep-Alive: timeout=30
11-30 17:27:39.454 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = Vary: Accept-Encoding
11-30 17:27:39.454 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = X-Ratelimit-Remaining2: 99
11-30 17:27:39.455 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = X-Ratelimit-Limit2: 100
11-30 17:27:39.455 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = Expires: Sun, 1 Jan 2006 01:00:00 GMT
11-30 17:27:39.455 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = Pragma: no-cache
11-30 17:27:39.455 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = Cache-Control: must-revalidate, no-cache, private
11-30 17:27:39.455 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = Set-Cookie: bid=IMz-P3yeOSw; Expires=Fri, 30-Nov-18 09:27:37 GMT; Domain=.douban.com; Path=/
11-30 17:27:39.455 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = X-DOUBAN-NEWBID: IMz-P3yeOSw
11-30 17:27:39.455 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = X-DAE-Node: daisy3d
11-30 17:27:39.455 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = X-DAE-App: book
11-30 17:27:39.455 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = Server: dae
11-30 17:27:39.457 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = 
11-30 17:27:39.457 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = {"rating":{"max":10,"numRaters":11413,"average":"9.2","min":0},"subtiitle":"","author_intro":"圣埃克苏佩里(1900-1944)1900年,尼采逝世。这一年,安德烈・纪德在布鲁塞尔一次会议上宣...}
11-30 17:27:39.457 8857-14147/zj.playretrofit I/PlayReTro: retrofitBack = <-- END HTTP (6406-byte body)
11-30 17:27:39.461 8857-8857/zj.playretrofit D/PlayReTro: ResponseBean{count=0, start=0, total=0, title='小王子', subjects=null}

Demo下载,博客推荐

Demo下载:
http://download.csdn.net/download/user11223344abc/10139703

博客推荐:
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0915/3460.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值