本篇是 Stone_ZH 的第二篇投稿,他的第一篇文章是ToolBar封装。
之前我推送过一片Retrofit源码分析的文章,而本篇将从 url 讲起,带你从不一样的角度理解Retrofit,并分享作者自己的封装思路。
Stone_ZH 的博客地址:
http://blog.csdn.net/zzz_zzz_z
Retrofit开源项目地址
https://github.com/square/retrofit
Retrofit项目官网
http://square.github.io/retrofit
上官网可能要梯子,大家自备,官网上有它的一系列基本用法,以及它的介绍:A type-safe HTTP client for Android and Java,它和 Okhttp 一样都是 square 公司的开源项目。
RESTful Api
在讲怎么用之前需要简单了解下 RESTful Api,看下面设计的三个删除评论的 api:
http://test.net/?method=comment.del&id=x ①
http://test.net/comment/del/id/x ②
而 RESTful Api 则是:
[DELETE] http://test.net/comments/1 ③
我们对比可以发现 ① 和 ② URL 中,都有 del 的动作指示。
SOAP Web API 采用RPC风格,它采用面向功能的架构,所以我们在设计 SOAP Web API 的时候首相考虑的是应高提供怎样的功能(或者操作)。
而 RESTful Api 是面向资源的架构。是查询、新增、修改、删除,都与该资源无关。
RESTful Api 是以 HTTP 协议为强烈依托的,将类似于 ①和② 这种以功能为主导的 URL 风格舍弃,还原 URL 的本质,它的宗旨就是一个 URL 就应该是一个资源,不能包含任何动作,如下所示:
URL的简单构成
构成一般是这样的:
[scheme:][//authority][path][?query]
看下面一个url:
http://www.java2s.com:8080/yourpath/fileName.htm?stove=10&path=32&id=4
scheme: http
authority: www.java2s.com:8080
path: /yourpath/fileName.htm
query: 在?后的部分为:stove=10&path=32&id=4
又由于 authority 又一步可以划分为 host:port 形式,其中 host:port 用冒号分隔,冒号前的是 host,冒号后的是 port,所以:
host: www.java2s.com
port: 8080
这里是url中的参数,除了url中的参数还有两个http协议中常用参数是:
header(请求头)和 body(常用于post请求中的请求体,有多种封装方法,不暴露在url中)这两个参数。
可以看出整个网络请求中参数主要可以分成:scheme、authority、path、query、header、body 这六块,下面主要看下 Retrofit 怎么配置这六块参数的。
参数配置
1、scheme 和 authority
在 retrofit 中将这两者合体称为 baseurl,接口用法如下:
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
2、header
(1)、静态header(分为单个键值对和多个键值对两种注解方式):
单个键值对注解:
@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("users/{username}")
Call<User> getUser(@Path("username") String username);
(2)、动态header(分为局部动态header和全局动态header)
a、局部动态header(分为单个键值对header和多个键值对header):
单个键值对局部动态header:
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
多个键值对局部动态header(retrofit:2.1.0 新加的):
@GET("user")
Call<User> getUser(@HeaderMap Map<String, String> headerMap)
b、全局动态header(适用于项目中的header规则一致的情况)
这里是用了 OkHttp 的 interceptor:
3、path(这里只看下GET请求,POST, PUT, DELETE请求一样处理)
这里分为带参数和不带参数两种:
不带参数的:
@GET("widget/list")
Call<List<Widget>> widgetList();
带参数的:
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
这里是通过 @Path(“user”) 注解实现参数传递。
4、query
以 GET请求 为例提供了两种注解方式(单个键值对和多个键值对),如下:
单个键值对:
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
多个键值对:
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
5、body
大多用于 POST请求 中:
@POST("users/new")
Call<User> createUser(@Body User user);
这里我是将其单独封在一个类中(AppClient)。
Retrofit 中网络请求实际上用的还是他自家的 OkHttp,所以如果要配置请求的一些全局参数还是得先创建一个 OkHttp 的实例对象,然后一一配置,上面讲了配置 全局header 也是这样处理的,所以这里我将其使用分成了三步:
这里首先要配三个库(retrofit库,json转化库,log的截断器库):
构建OkHttpClient实例
配置一些请求的全局参数:
这里做了四件事:
1、httpClientBuilder.hostnameVerifier 这里是针对我公司的Https证书问题,详情看这里:
https证书问题
http://blog.csdn.net/zzz_zzz_z/article/details/51824765
2、通过拦截器设置header,可以看上面参数设置那里的讲解。
3、设置请求超时时间和读取数据时间:
.connectTimeout(10, TimeUnit.SECONDS)
.readTimeout(10, TimeUnit.SECONDS);
4、设置 log拦截器,这里设置之后可以在 logcat 中看到每个网络请求的请求参数和返回结果以及请求时长,非常好用,当然先要配置下上面我配置的第三个库。
构建Retrofit实例
这里配置可以看出,Retrofit 内部也是封了一个 Okhttp 的实例,这里做了四件事:
1、设置了 baseurl 参数,可以看我上面参数配置的讲解。
2、设置了 OkHttpClient 实例。
3、gson转化工厂:addConverterFactory(GsonConverterFactory.create()),这里 Retrofit 内部会根据这个转换工厂及返回数据所指定的泛型实现直接转换。
4、网络请求的适配器工厂:addCallAdapterFactory(RxJavaCallAdapterFactory.create()),这个可以忽略暂时,因为我项目里使用了RXjava和Retrofit,后续我会写一篇 MVP+RXjava+Retrofit 的封装使用。
构建Call
开始网络请求并实现回调,这里先要配置请求参数,我封了个类专门用来设置请求接口:
构建call实例对象,开始网络请求并实现回调:
Retrofit 这个库将 ResfulApi 的几种请求都通过注解进行了一系列封装,整个请求流程比 OkHttp 简洁了很多,同时它可以通过设置GSON转换工厂内部实现返回数据的转化,使用过程非常简洁清晰,同时可以配合现在流行的 RXjava 一起使用,下面我准备搞一篇MVP+RX+Retrofit的封装使用,Okhttp可以换啦!
如有不足之处还请大家多多指正!
如果你有好的技术文章想和大家分享,欢迎向我的公众号投稿,投稿具体细节请在公众号主页点击“投稿”菜单查看。
欢迎长按下图 -> 识别图中二维码或者扫一扫关注我的公众号: