注解深入浅出(五Retrofit 中的注解) Posted 2023-02-06 持续学习刻意练习
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了注解深入浅出(五Retrofit 中的注解)相关的知识,希望对你有一定的参考价值。
第二章注解深入浅出
五、Retrofit 中的注解
retrofit-2.9.0 共有 25 个注解,根据功能大概分为三类:
5.1 请求方法类注解
有 8 个,分别是:GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、HTTP 。
序号 名称 作用 备注 1 GET
用于发送一个 GET 请求 GET 注解一般必须添加相对路径或绝对路径或全路径,如果不想在 GET 注解后添加请求路径则可以在方法的第一个参数中用 @Url 注解添加请求路径
分别对应 HTTP 的请求方法 接收一个字符串表示接口 path 与 baseUrl 组成完成的 Ur 可以不指定,结合 @Url 注解使用 url 中可以使用变量,如 id,并使用 @Path("id") 注解为 id 提供值 2 POST
用于发送一个 POST 请求 POST 注解一般必须添加相对路径或绝对路径或全路径,如果不想在 POST 注解后添加请求路径则可以在方法的第一个参数中用 @Url 注解添加请求路径 3 PUT
用于发送一个 PUT 请求 PUT 注解一般必须添加相对路径或绝对路径或全路径,如果不想在 PUT 注解后添加请求路径则可以在方法的第一个参数中用 @Url 注解添加请求路径 4 DELETE
用于发送一个 DELETE 请求 DELETE 注解一般必须添加相对路径或绝对路径或全路径,如果不想在 DELETE 注解后添加请求路径,则可以在方法的第一个参数中用 @Url 注解添加请求路径 5 PATCH
用于发送一个 PATCH 请求 在 URL 路径段中替换指定的参数值,使用 String.valueOf() 和 URL 编码将转换为字符串 使用该注解定义的参数的值不可为空 参数值默认使用 URL 编码 6 HEAD
用于发送一个 HEAD 请求 HEAD 注解一般必须添加相对路径或绝对路径或全路径,如果不想在 HEAD 注解后添加请求路径,则可以在方法的第一个参数中用 @Url 注解添加请求路径 7 OPTIONS
用于发送一个 OPTIONS 请求 OPTIONS 注解一般必须添加相对路径或绝对路径或全路径,如果不想在 OPTIONS 注解后添加请求路径,则可以在方法的第一个参数中用 @Url 注解添加请求路径 8 HTTP
可用于替代以上 7 个以其它扩展方法 有 3 个属性:method、path、hasBody
5.2 标记类注解
有 3 个,分别是 FormUrlEncoded、Multipart、Streaming 。
序号 名称 作用 1 FormUrlEncoded
用于修饰 Field 注解和 FieldMap 注解 使用该注解,表示请求正文将使用表单网址编码。字段应该声明为参数,并用 @Field 注释或 @FieldMap 注释 使用 FormUrlEncoded 注释的请求将具 “application / x-www-form-urlencoded”MIME 类型。字段名称和值将先进行 UTF-8 进行编码,再根据 RFC-3986 进行 URI 编码 2 Multipart
作用于方法 使用该注解表示请求体是多部分的,每一部分作为一个参数且用 Part 注释声明,例如:文件上传 3 Streaming
作用于方法 处理返回 Response 的方法的响应体,即没有将 body() 转换为 byte[] 未使用该注解,默认会把数据全部载入内存,之后通过流获取数据也是读取内存中数据,所以返回数据较大时,需要使用该注解
5.3 参数注解
有 11 个,分别是:Body、Field、FieldMap、Part、PartMap、HeaderMap、Path、Query、QueryMap、QueryName、Url 。
序号 名称 作用 1 Body
作用于方法的参数 使用该注解定义的参数不可为 null 当你发送一个 post 或 put 请求,但是又不想作为请求参数或表单的方式发送请求时,使用该注解定义的参数可以直接传入一个实体类,retrofit 会通过 convert 把该实体序列化并将序列化后的结果直接作为请求体发送出去 2 Field
作用于方法的参数 用于发送一个表单请求 用 String.valueOf() 把参数值转换为 String,然后进行 URL 编码,当参数值为 null 值时,会自动忽略,如果传入的是一个 List 或 Array,则为每一个非空的 item 拼接一个键值对,每一个键值对中的键是相同的,值就是非空 item 的值,如果 item 的值有空格,在拼接时会自动忽略 3 FieldMap
作用于方法的参数 用于发送一个表单请求 map 中每一项的键和值都不能为空,否则会抛出 IllegalArgumentException 异常 4 Part
作用于方法的参数,用于定义 Multipart 请求的每个 part 使用该注解定义的参数,参数值可以为空,为空时则忽略 使用该注解定义的参数类型有以下三种方式可选 如果类型是 okhttp3.MultipartBody.Part,内容将被直接使用,省略 part 中的名称,即 @PartMultipartBody.Part part 如果类型是 RequestBody,那么该值将直接与其内容类型一起使用,在注解中提供 part 名称,例如:@Part ("foo") RequestBody foo 其他对象类型将通过使用转换器转换为适当的格式,在注解中提供 part 名称,例如:@Part ("foo") Image photo
5 PartMap
作用于方法的参数,以 map 的方式定义 Multipart 请求的每个 part map 中每一项的键和值都不能为空,否则会抛出 IllegalArgumentException 异常 使用该注解定义的参数类型有以下两种方式可选: 如果类型是 RequestBody,那么该值将直接与其内容类型一起使用 其他对象类型将通过使用转换器转换为适当的格式
6 HeaderMap
作用于方法的参数,用于添加请求头 以 map 的方式添加多个请求头,map 中的 key 为请求头的名称,value 为请求头的值,且 value 使用 String.valueOf() 统一转换为 String 类型 map 中每一项的键和值都不能为空,否则会抛出 IllegalArgumentException 异常 7 Path 8 Query
作用于方法的参数 用于添加查询参数,即请求参数 动态拼接一个参数到 URL 后 参数值通过 String.valueOf() 转换为 String 并进行 URL 编码 使用该注解定义的参数,参数值可以为空,为空时忽略该值,当传入一个 List 或 Array 时,为每个非空 item 拼接请求键值对,所有的键时统一的 9 QueryMap
作用于方法的参数 以 map 的形式添加查询参数,即请求参数 动态拼接多个参数到 URL 后 参数的键和值都通过 String.valueOf() 转换为 String 格式 map 的键和值默认进行 URL 编码 map 中每一项的键和值都不能为空,否则会抛出 IllegalArgumentException 异常 10 QueryName
11 Url
5.4 其他注解
有 3 个,分别是:Header、Headers、Tag 。
序号 名称 作用 1 Header
作用于方法的参数,用于添加请求头 使用该注解定义的请求头可以为空,当为空时,会自动忽略,当传入一个 List 或 array 时,为拼接每个非空的 item 的值到请求头中 具有相同名称的请求头不会相互覆盖,而是会照样添加到请求头中 2 Headers
作用于方法,用于添加一个或多个请求头 具有相同名称的请求头不会互相覆盖,而是照样添加到请求头中 3 Tag
5.5 注意事项
以上部分注解真正的实现在 ParameterHandler 类中,每个注解的真正实现都是 ParameterHandler 类中的一个 final 类型的内部类,每个内部类都对各个注解的使用要求做了限制,比如参数是否为空,键和值是否为空等。
FromUrlEncoded 注解和 Multipart 注解不能同时使用,否则会抛出 methodError(“Only one encoding annotation is allowed”),可在 ServiceMethod 类中 parseMethodAnnotation() 方法中找到不能同时使用的具体原因。
Path 注解与 Url 注解不同时使用,否则会抛出 parameterError(p, “@Path parameters may not be used with @Url”),可在 ServiceMethod 类中找到不能同时使用的具体代码,其实原因也很好理解,Path 注解用于替换 url 路径中的参数,这就要求在使用 path 注解时,必须已经存在请求路径,不然没法替换路径中指定的参数,而 Url 注解是在参数中指定的请求路径的,这个时候指定请求路径已经晚了,path 注解找不到请求路径,更别提更换请求路径中的参数了。
对于 FieldMap、HeaderMap、PartMap、QueryMap 这四种作用于方法的注解,其参数类型必须为 Map 的实例,且 key 的类型必须为 String 类型,否则会抛出异常,以 PartMap 注解为例,会抛出 parameterError(p, “@PartMap keys must be of type String:” + keyType)
使用 Body 注解的参数不能使用 form 或 multi-part 编码,即如果为方法使用了 FormUrlEncoded 或 Multipart 注解,则方法的参数中不能使用 Body 注解,否则会抛出异常 parameterError(p, “@Body parameters cannot be used with form or multi-part encoding”)
以上是关于注解深入浅出(五Retrofit 中的注解)的主要内容,如果未能解决你的问题,请参考以下文章
Retrofit 中的注解以及如何自定义接口方法注解
理解Android中的注解与反射
Java反射学习总结五(Annotation(注解)-基础篇)
Java反射学习总结五(Annotation(注解)-基础篇)
五Spring中的@Import注解
注解深入浅出(一注解 Annotations)