Retrofit--请求方法那些事儿

来源:互联网 发布:网络回路检测 编辑:程序博客网 时间:2024/06/12 18:53

在上一节中,实现了Retrofit简单的网络请求,当然了,这远远不够,我们需要更加多的功能,这节介绍在Retrofit中如何定义请求方法

如何描述一个Http请求方法

就像在上一节中,在一个接口中定义一个Http请求方法,如下所示,当然了这只是简单的GET方法,接下来我们将会接触更加多不同类型的方法。

public interface ZhiHuClient {//    https://news-at.zhihu.com/api/4/news/before/20170707    @GET("/api/4/news/before/{date}")    Call<ZhiHuPaseNews> getZhiHuPastNews(@Path("date") String date);}

Http请求方法

在上一节中,我们知道可以是使用Javaannotation(注释)来描述一个Http请求方法,在Http中还有类似的GET,PUT,POST,DELETE等请求方法,在Retrofit中也有相对应的注释来实现,例如@GET,@PUT,POST,@DELETE。下面是一个简单的例子。

public interface UserClient {    @GET("/user/info")    Call<UserInfo> getUserInfo();    @PUT("/user/info")    Call<UserInfo> updateUserInfo(@Body UserInfo userInfo);    @DELETE("/user")    Call<Void> deleteUser();}

Http资源定位

另外,我们需要在注释中添加相对路径(相对于BaseUrl),例如上一节中的@GET("/api/4/news/before/{date}"),我们只需传相对路径,而不是绝对路径,像https://news-at.zhihu.com/api/4/news/before/20170707(这里的20170707是动态替换的),这样做的好处是我们只需传一次BaseUrl(https://news-at.zhihu.com),而且为我们动态替换BaseUrl提供了方便。

public interface ZhiHuClient {    //    https://news-at.zhihu.com/api/4/news/before/20170707    @GET("/api/4/news/before/{date}")    Call<ZhiHuPaseNews> getZhiHuPastNews(@Path("date") String date);    //全路径    @GET("https://news-at.zhihu.com/api/4/news/latest")    Call<ZhiHuPaseNews> getZhiHuLatestNews();}

我们来验证一下

   //请求的Base url        String API_BASE_URL = "https://news-at.zhihu.com/";        //通过给okhttpClient设置拦截器,能很方便的看到网络返回的数据        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);        httpClient.addInterceptor(httpLoggingInterceptor);        //简单配置ZhiHuClient        Retrofit.Builder builder = new Retrofit.Builder()                .baseUrl(API_BASE_URL)                .addConverterFactory(GsonConverterFactory.create());        Retrofit retrofit = builder.client(httpClient.build()).build();        ZhiHuClient client = retrofit.create(ZhiHuClient.class);        //传入参数,动态替换url上的参数//        Call<ZhiHuPaseNews> call = client.getZhiHuPastNews("20170707");        //动态替换baseUrl        Call<ZhiHuPaseNews> call = client.getZhiHuLatestNews();        //异步请求        call.enqueue(new Callback<ZhiHuPaseNews>() {            @Override            public void onResponse(Call<ZhiHuPaseNews> call, Response<ZhiHuPaseNews> response) {                //成功返回的回调                //TODO:把返回结果展示            }            @Override            public void onFailure(Call<ZhiHuPaseNews> call, Throwable t) {                //失败返回的回调                //TODO:处理返回失败            }        });

我们可以使从控制台中看到
这里写图片描述
请求地址的BaseUrl已经被替换了。

函数名和返回值

上面我们讨论了使用Java的注释描述Http请求方法,现在来看看方法Call<ZhiHuPaseNews> getZhiHuPastNews(@Path("date") String date);这里有三部分:

  1. 函数名
  2. 返回值
  3. 参数

最简单的就是函数名了,像我们平时写代码一样,Retrofi没有做出限制。

但是返回类型是严格控制的,你必须定义你想从服务器中想要获取的类型,例如,我们想获取知乎过往消息,可以这样Call<ZhiHuPaseNews>,ZhiHuPaseNews包含了服务器映射的属性(可以使用GsonFormat生成),然后Retrofi完成之间的属性转换,如果想要的是原始数据,我们可以这样定义Call<ResponseBody>,使用ResponseBody代替ZhiHuPaseNews,如果不关心服务器返回是什么,我们可以Call<Void> getZhiHuPastNews,,使用Void代替ZhiHuPaseNews

根据Http请求方法的不同,相对应的函数参数也会不一样,例如

  • @Body: 把Java对象当作请求体
  • @Url: 使用动态URL
  • @Field: 以form-urlencoded发送数据

路径参数(Path Parameters)

REST API是基于动态URL的,通过替换Url其中的一部分,访问网络,例如https://news-at.zhihu.com/api/4/news/before/20170707,20170707是我们指定的访问日期,Retrofit使我们很方便的替换这些参数,例如:

public interface ZhiHuClient {    @GET("/api/4/news/before/{date}")    Call<ZhiHuPaseNews> getZhiHuPastNews(@Path("date") String date);    }

{date}表示值是动态的,并在请求时设置,如果在URL中包含类似{date}的路径参数,那么就必须在函数参数中添加@Path参数,@Path,匹配路径参数(这里指的是@Path("date"))。

请求参数(Query Parameters)

动态URL中,Query Parameters也是用得很多,例如这样的请求地址http://www.tngou.net/api/info/list?id=3&rows=10,?id=3是一个查询参数,与路径参数不同的是,我们不需把注释添加到URL中,只需简单的把@Query添加到函数参数中即可,Retrofi将自动把这些转换到请求方法中。

public interface TngouClient {    //    ?id=3&rows=10    @GET("/api/info/list")    Call<TngouHealth> getTngouHealth(@Query("id") Integer id, @Query("rows") Integer rows);}

如果传入一个null值,Retrofi将忽略它。

我们来验证一下:

  //请求的Base url        String API_BASE_URL = "http://www.tngou.net/";        //通过给okhttpClient设置拦截器,能很方便的看到网络返回的数据        OkHttpClient.Builder httpClient = new OkHttpClient.Builder();        HttpLoggingInterceptor httpLoggingInterceptor = new HttpLoggingInterceptor();        httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);        httpClient.addInterceptor(httpLoggingInterceptor);        //简单配置tngouClient        Retrofit.Builder builder = new Retrofit.Builder()                .baseUrl(API_BASE_URL)                .addConverterFactory(GsonConverterFactory.create());        Retrofit retrofit = builder.client(httpClient.build()).build();        TngouClient tngouClient = retrofit.create(TngouClient.class);        Call<TngouHealth> call = tngouClient.getTngouHealth(3, 10);        //异步请求        call.enqueue(new Callback<TngouHealth>() {            @Override            public void onResponse(Call<TngouHealth> call, Response<TngouHealth> response) {            }            @Override            public void onFailure(Call<TngouHealth> call, Throwable t) {            }        });

在控制台中可以看到我们的请求地址正是我们所希望的那样
这里写图片描述

如果第二个参数传入为null会是怎么样?

Call<TngouHealth> call = tngouClient.getTngouHealth(3, null);

这里写图片描述
从请求地址可以看到,如果传入null值,Retrofit将忽略它,

总结

这节简单的介绍了HTTP方法、返回类型、路径和查询参数等。

下载地址

参考

原创粉丝点击