请求参数注解(三)
大约 3 分钟
前言
在上一篇文章 请求参数注解(二) 中我们学习了 Header
注解,本篇文章我们学习了 Field
相关的注解。
从上图可以看出与 Field
相关的注解有:
@Field
@FieldMap
@Field
@Field
注解标记HTTP接口方法中的一个参数,表示这个参数是 Form
表单里的一个字段。参数的值、集合或数组中的子项会经过 Retrofit#stringConverter(Type, Annotation[])
转换,如果没有找到匹配的字符串转换器则使用 Object#toString()
,然后再进过 URL 编码。
@Field
注解有两个参数,分别为:
value
:必选,表示字段名,encoded
:可选,表示value
对应的字段名和字段值是否已经经过 URL 编码,默认false
,
简单使用示例:
interface Service {
@FormUrlEncoded
@POST("foo/bar")
Call<ResponseBody> method(@Field("lang") String lang);
}
Service service = retrofit.create(Service.class);
service.method("zh");
@Field
注解使用时有以下几点需要注意:
@Field
注解仅能在被@FormUrlEncoded
注解标记的方法中使用,参数值为
null
的话会被忽略,参数值为集合或数组时,会忽略其为
null
的子项,如果集合类型不是参数化类型,则抛出异常,即:不能直接使用原始类型:// 错误示例 interface Service { @FormUrlEncoded @POST("foo/bar") Call<ResponseBody> method(@Field("lang") List lang); }
@FieldMap
@FieldMap
注解标记HTTP接口方法中的一个参数,表示这个参数是 Form
表单里的一个或多个字段。
@FieldMap
注解目前只有一个参数:
encoded
:可选,表示字段名和字段值是否已经经过 URL 编码,默认false
,
简单使用示例:
interface Service {
@FormUrlEncoded
@POST("foo/bar")
Call<ResponseBody> method(@FieldMap Map<String, String> fields);
}
Service service = retrofit.create(Service.class);
service.method(ImmutableMap.of("foo", "bar", "kit", "kat");
// request body: foo=bar&kit=kat
@FieldMap
注解使用时有以下几点需要注意:
@Field
注解仅能在被@FormUrlEncoded
注解标记的方法中使用,- 被标注的参数类型必须是
Map
,否则抛出异常, Map
中键的类型必须是String
类型,否则抛出异常,如果键的值为null
,则抛出异常,Map
中值没有限定类型,如果值为null
,则抛出异常,然后会经过Retrofit#stringConverter(Type, Annotation[])
转换,如果没有找到匹配的字符串转换器,则使用Object#toString()
,如果转换后的值为null
,则抛出异常,
总结
@Field
和 @FieldMap
注解相对于 Header
相关的注解简单一些,在 Header
相关的注解中我们区分了静态和动态类型,那么本文学习的两个注解都应该属于动态类型,它俩的区别如下表所示:
注解 | 类型 | 适用场景 |
---|---|---|
@Field | 动态 | 明确字段名,不明确字段值 |
@FieldMap | 动态 | 1.字段名和字段值都不明确 2.一次传入多个字段 |
我们只要记住它俩仅能在 @FormUrlEncoded
注解标记的HTTP接口方法使用,一般就不会出错了。
希望可以帮你更好的使用 Retrofit,happy~