闭门造车姚师傅

Retrofit源码分析:注解部分

字数统计: 1.3k阅读时长: 5 min
2018/02/02 266 Share

Retrofit 中的注解定义在 retrofit.http 包下,包含了 Retrofit 用到的注解。主要分为两类,HTTP请求注解(针对函数)和参数注解(针对参数)。

本文对各种注解的用法做了个简单的介绍。

This post includes a simple introduction to retrofit annotations and some concise example.

// 上一行是为了谷歌爸爸的 SEO ( 逃

Annotations for interface methods to control the HTTP request behavior.

package-info.java 中写到, 这里包含了定义的Retrofit接口中的方法用来控制HTTP请求行为的注解.


参数注解

@Query & @QueryMap

GET 结合使用,使用 @QueryMap 可以动态添加字段

  • 简单示例:
    1
    2
    @GET("/friends")
    Call<ResponseBody> friends(@Query("page") int page);

调用 foo.friends(1) 产生 /friends?page=1

  • 参数为null的情况:
    1
    2
    @GET("/friends")
    Call<ResponseBody> friends(@Query("group") String group);

调用 foo.friends(null) 产生 /friends

  • 数组和 varargs 示例:
    1
    2
    @GET("/friends")
    Call<ResponseBody> friends(@Query("group") String... groups);

调用 foo.friends("coworker", "bowling") 产生 /friends?group=coworker&group=bowling

@QueryName

适用于没有 的查询参数

1
2
@GET("/friends")
Call<ResponseBody> friends(@QueryName String... filters);

foo.friends("contains(Bob)", "age(42)") –> /friends?contains(Bob)&age(42)

直接是 ?filter1&filter2 而不是 ?filter1=foo&filter2=bar

@Field & @FieldMap

POST 结合使用,使用 @FieldMap 可以动态添加

  • 简单示例:
    1
    2
    3
    4
    @FormUrlEncoded
    @POST("/")
    Call<ResponseBody> example(@Field("name") String name,
    @Field("occupation") String occupation);

调用 foo.example("Bob Smith", "President") 所产生请求的 body 为 name=Bob+Smith&occupation=President

  • 数组和 varargs 示例:参考 @GET

@Header & @HeaderMap

@Header@HeaderMap 用来添加请求头

需要注意的地方:

  • header 不会相互覆盖,重复的添加会在请求头产生多行记录
  • 对于值 null 的情况,键会被忽略
  • 值的类型为 List 或 Array 时,其中的非空值会被分解为多条。 eg. name : ["Jiang", "Min"] --> name: Jiang \r\n name: Min

@Body

在参数上使用这个注解来直接控制 POST/PUT 请求的 body 。如果是对象的化将由 Retrofit中指定的 Converter 来进行序列化,序列化结果将被直接设置为请求的 body 。比如,直接使用和后端对应的实体类作为参数,使用 Gson 来进行序列化)

一个例子:

1
2
3
4
5
6
/* 接口定义 */
@POST("/abc") // baseUrl: http://sample.com/
Call<ResponseBody> getSomething(@Body String body);
/* 测试代码 */
retrofit.create(ExampleService.class)
.getSomething("{name:'Chairman Jiang'}").enqueue(....);
1
2
3
4
5
OkHttp: --> POST http://sample.com/abc
OkHttp: Content-Type: application/json; charset=UTF-8
OkHttp: Content-Length: 25
OkHttp: "{name:'Chairman Jiang'}"
OkHttp: --> END POST (25-byte body)

@Part & @PartMap

与方法注解 @Multipart 结合使用

根据修饰的参数类型分为三类

  1. okhttp3.MultipartBody.Part , Retrofit 将直接使用参数内包含的信息。
    @Part MultipartBody.Part part ,使用默认注解参数。
  2. okhttp3.RequestBody RequestBody , 同样 Retrofit 将直接使用参数内包含的信息。同时会用到 @Part 的参数。 比如 @Part("foo") RequestBody foo
  3. others , 其他类型的对象将经由 Converter 来转换成合适的格式,也会用到 @Part 的参数。

@Url

用来动态指定要请求的 URL

@Path

@Path 注解用来替换 url 的 key

1
2
GET("/image/{id}")
Call<ResponseBody> example(@Path("id") int id);

foo.example(233) –> /image/233


方法注解

@GET

GET 请求用来获取服务器端的资源。GET 仅仅应该用来获取数据而不应该产生其他副作用。

@POST

POST 被设计用来请求 web 服务器接受包含在 请求消息正文(request message body) 中的数据。当上传文件或提交完整的网页表单时,经常使用它。

用途比较广泛,比如 公告板消息、一条评论、网页表单产生的一大坨数据、一些可以放到数据库中的实体数据 等等。

@PUT

PUT 一般用来请求服务器存储特定 URI 便是的资源。服务器一般会更新(已经存在)或新建(之前不存在)资源文件。

@DELETE

字面意思,删除

@PATCH

Path ~ 补丁,对特定资源进行部分(partial)修改。

@OPTIONS

对于 OPTIONS 请求,服务器返回该 URL 支持的所有 HTTP 请求种类。

HEAD 基本等价于没有 response bodyGET 请求。如果返回的数据在 response header 中,使用 HEAD 会很合适。

@HTTP

使用自定义的 HTTP 操作,比如:

1
2
@HTTP(method = "KISS", path = "/beauties/girlfriend")
Call<ResponseBody> foo();

此注解还可以用来发送带 body 的 DELETE 请求:

1
2
@HTTP(method = "DELETE", path = "remove/", hasBody = true)
Call<ResponseBody> deleteObject(@Body RequestBody object);

@Multipart

表示请求体为 multi-part , 这些 part 应该使用 @Part 注解。

一个示例:

1
2
3
@Multipart
@POST("/")
Call<ResponseBody> example(@Part("description") String description, @Part(value = "image", encoding = "8-bit") RequestBody image);

@FormUrlEncoded

表示请求体会使用 URL形式的表单编码(form url encoding) ,字段(体现在接口中是形参)应该使用 @Part 注解。使用这个注解产生的请求的请求头中会有 application/x-www-form-urlencoded MIME 类型。字段的键值在编码前会先被编码为 UTF-8

@Headers

对于 header 的值确定的情况,可以直接使用作用于方法的注解

就像下面这样:

1
2
3
4
5
6
7
8
@Headers("Cache-Control: max-age=640000")
@POST("/abc")
.....或....
@Headers({
"X-Foo: Bar",
"X-Ping: Pong"
})
@POST("/abc")

@Streaming

将方法返回的 okhttp3.Response Response 保持原样,不将 okhttp3.Response#body() body() 转换为 byte[]


Ref:

Hypertext Transfer Protocol - Wikipedia

Retrofit 中的源码注释

via boileryao

happy coding :)

Powered By Valine
v1.5.2
CATALOG
  1. 1. 参数注解
  2. 2. 方法注解