请求参数注解(二)
前言
在上一篇文章 请求参数注解(一) 中我们学习了 @Url
和 @Path
注解,本篇文章我们学习下与 Header
相关的注解。
从上图可以看出与 Header
相关的注解有:
@Header
@Headers
@HeaderMap
@Header
@Header
注解标记HTTP接口方法中的一个参数,表示这个参数参与HTTP请求头的构建。参数的值,集合或数组中的子项会经过 Retrofit#stringConverter(Type, Annotation[])
转换,如果没有找到匹配的字符串转换器则使用 Object#toString()
。
@Header
注解有两个参数,分别为:
value
:必选,表示请求头中的键 Key,allowUnsafeNonAsciiValues
:可选,默认情况下,键和值仅允许 ascii 中的值,如果指定allowUnsafeNonAsciiValues=true
,可以改变上述行为,主要是适用于世界上其他语言,
简单使用示例:
interface Service {
@GET("foo/bar")
Call<ResponseBody> method(@Header("Accept-Language") String lang);
}
Service service = retrofit.create(Service.class);
service.method("zh");
@Header
注解使用时有以下几点需要注意:
参数值为
null
的话会被忽略,参数值为集合或数组时,会忽略其为
null
的子项,如果集合类型且不是参数化类型,则抛出异常,即:不能直接使用原始类型:// 错误示例 interface Service { @GET("foo/bar") Call<ResponseBody> method(@Header("Accept-Language") List lang); }
相同键的请求头不会相互覆盖,所有相同键的请求头都会在HTTP请求中,
@HeaderMap
@HeaderMap
注解也是标记HTTP接口方法中的一个参数,表示这个参数参与HTTP请求头的构建。
@HeaderMap
注解目前只有一个参数:
allowUnsafeNonAsciiValues
:可选,其作用与@Header
注解中的相同,
简单使用示例:
interface Service {
@GET("foo/bar")
Call<ResponseBody> method(@HeaderMap Map<String, String> headers);
}
Service service = retrofit.create(Service.class);
service.method(ImmutableMap.of("Accept", "text/plain", "Accept-Charset", "utf-8"));
@HeaderMap
注解使用时有以下几点需要注意:
- 被标注的参数类型必须是
Map
或者okhttp3.Headers
,否则抛出异常, - 如果是
Map
类型,Map
中键的类型必须是String
类型,否则抛出异常, - 如果是
Map
类型,Map
中值没有限定类型,但是会经过Retrofit#stringConverter(Type, Annotation[])
转换,如果没有找到匹配的字符串转换器,则使用Object#toString()
。
@Headers
Headers
注解标记一个HTTP接口方法,表示这个HTTP接口方法所包含的请求头数据。
Headers
注解有两个参数,分别为:
value
:必选,字符串数组类型,其子项格式必须为键值对:Key: Value
,allowUnsafeNonAsciiValues
:可选,其作用与@Header
注解中的相同,
简单使用示例:
interface Service {
@GET("foo/bar")
@Headers({"ping: pong", "kit: kat"})
Call<ResponseBody> method();
}
@Headers
注解使用时有以下几点需要注意:
- 数组不能为空,否则抛出异常,
- 数组子项格式必须为键值对:
Key: Value
,缺少Key
、:
或Value
都会抛出异常,
总结
本文学习了 @Header
、@HeaderMap
和 @@Headers
请求参数注解的简单使用与注意事项,现简单总结下各自的作用与分类。
静态 Header
静态 Header 是我们已经明确知道当前HTTP请求中需要包含的请求头,比如:Content-Type
,那么我们就可以以字面量的形式通过 @Headers
注解直接声明在HTTP接口方法之上,这种方式即提升了代码结构,又增强了代码可读性,降低后续的维护成本。
动态 Header
既然有静态 Header,那么就有动态 Header。静态 Header 的优势比较明显,同时劣势也比较鲜明。
当我们知道当前HTTP请求需要包含一些请求头的键,但是不确定请求头的值时,那么我们可以通过 @Header
注解声明在HTTP接口方法的某个参数上,在实际调用HTTP接口方法发起HTTP请求时再传入请求头的值,这种方式在一定程度上增加了请求头设置的灵活性。
当我们不确定当前HTTP请求需要包含哪些请求头,即完全不确定请求头的键和值时,或者请求头的键和值是由外部提供的,那么我们可以通过 @HeaderMap
注解声明在HTTP接口方法的某个参数上,在实际调用HTTP接口方法发起HTTP请求时把请求头信息封装成 Map
类型传入,这种方式极大的提高了请求头设置的灵活性,但是灵活性的提高,对它的一些限制/校验会相应提高,易用性则会相应降低,使用过程中的出错率也会相应增加。
注解 | 类型 | 适用场景 |
---|---|---|
@Header | 动态 Header | 明确键,不明确值 |
@HeaderMap | 动态 Header | 1.键和值都不明确 2.一次传入多个 Header |
@Headers | 静态 Header | 键和值都明确 |
通过本文的学习,相信在实际工作中使用这两个注解时肯定是信手捏来。
希望可以帮你更好的使用 Retrofit,happy~