美文网首页
Retrofit(一)

Retrofit(一)

作者: 涛涛123759 | 来源:发表于2020-06-17 16:24 被阅读0次

随着Google对HttpClient的摒弃,和Volley的逐渐没落,OkHttp开始异军突起,Retrofit对OkHttp进行了强制依赖。Retrofit是由Square公司出品的针对于Android和Java的类型安全的Http客户端,如果看源码会发现其实本质上是OkHttp的封装,使用面向接口的方式进行网络请求,利用动态生成的代理类封装了网络接口请求的底层,其将请求返回JavaBean,对网络认证REST API进行了很友好的支持。retrofit是基于RESTful架构,使用Retrofit将会极大的提高我们应用的网络体验。

在gradle里面添加导入retrofit

    implementation  'com.squareup.retrofit2:retrofit:2.3.0'
    implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0'
    implementation 'com.squareup.retrofit2:converter-gson:2.3.0'

一、参数注解

1、@Query:作用于方法参数,用于添加查询参数,即请求参数
@GET("/list")
Call<ResponseBody> list(@Query("page") int page);
@GET("/list")
Call<ResponseBody> list(@Query("category") String category);
//传入一个数组
@GET("/list")
Call<ResponseBody> list(@Query("category") String... categories);
//不进行URL编码
@GET("/search")
Call<ResponseBody> list(@Query(value="foo", encoded=true) String foo);
2、@QueryMap:作用于方法的参数
//使用默认URL编码
@GET("/search")
Call<ResponseBody> list(@QueryMap Map<String, String> filters);
//不使用默认URL编码
@GET("/search")
Call<ResponseBody> list(@QueryMap(encoded=true) Map<String, String> filters);
3、@Body:作用于方法参数

使用@Body 注解定义的参数不能为null。
当你发送一个post或put请求,但是又不想作为请求参数或表单的方式发送请求时,使用该注解定义的参数可以直接传入一个实体类,retrofit会通过convert把该实体序列化并将序列化的结果直接作为请求体发送出去。

   public class Repo {
    private String owner;
    private String name;
    Repo(String owner, String name) {
      this.owner = owner;
      this.name = name;
    }
  }
    @POST("/")
    Call<ResponseBody> sendNormal(@Body Repo repo);
4、@Field:作用于方法的参数

用String.valueOf()把参数值转换为String,然后践行URL编码,当参数值为null是=时,会自动忽略,如果传入的是一个List或者array,则为每一个非空的item拼接一个键值对,每一个键值对中的键是相同的,值就是非空的item的值。如:name=张三&name=李四&name=王五,如果itme的值有空格,在拼接的时候会自动忽略,例如某个item的值为:张 三,则拼接后为name=张三。

//普通参数
@FormUrlEncoded
@POST("/")
Call<ResponseBody> example(@Field("name") String name,@Field("occupation") String occupation);

//固定或可变数组
@FormUrlEncoded
@POST("/list")
Call<ResponseBody> example(@Field("name") String... names);
5、@FieldMap:作用于方法的参数

map中的每一项的键和值都不能为空,否则抛出IllegalArgumentException异常。

@FormUrlEncoded
@POST("/things")
Call<ResponseBody> things(@FieldMap Map<String, String> fields);
6、@Part:作用于方法的参数,用于定义Multipart请求的每和part

使用该注解定义的参数,参数值可以为空,为空时,则忽略。

  • 1 okhttp2.MulitpartBody.Part,内容将被直接使用。省略part中的名称,即@Part MultipartBody.Part part
  • 2 如果类型是RequestBody,那么该值直接与其内容类型一起使用。在注释中提供part名称(例如,@Part("foo") RequestBody foo)
  • 3 其它对象类型将通过使用转换器转换为适当的格式。在注释中提供part名称(例如,@Part("foo") Image photo)。
@Multipart
@POST("/")
Call<ResponseBody> example(
       @Part("description") String description,
       @Part(value = "image", encoding = "8-bit") RequestBody image);
7、@PartMap:作用于方法的参数

以map的方式定义Multipart请求的每个part map中每一项的键和值都不能为空,否则抛出IllegalArgumentException异常。

  • 1 如果类型是RequestBody,那么该值将直接与其内容类型与其使用。
  • 2 其它对象类型将通过使用转换器转换为适当的格
8、@Header:作用于方法的参数,用于添加请求头

使用 @Header 注解 定义的请求头可以为空,当为空时,会自动忽略,当传入一个List或者array时,为拼接每个非空的item的值到请求头中。
具有相同名称的请求头不会相互覆盖,而是照样添加到请求头中

@GET("/")
Call<ResponseBody> foo(@Header("Accept-Language") String lang);
9、@Headers:作用于方法,用于添加一个或多个请求头中

具有相同名称的请求头不会相互覆盖,而是会照样添加到请求头中。

//添加一个请求头
 @Headers("Cache-Control: max-age=640000")
 @GET("/")

//添加多个请求头
@Headers({ "X-Foo: Bar", "X-Ping: Pong"})
@GET("/")
10、@Url: 作用于方法参数

用于添加请求的 接口地址

@GET
Call<ResponseBody> list(@Url String url);

二、(Content-Type)标记注解

1、@FormUrlEncoded:用于修饰Filed注解 和FileldMap注解

使用该注解,表示请求正文将使用表单网址编码。字段应该声明为参数,并用@Field注解和 @FieldMap注解,使用@FormUrlEncoded 注解的请求将具有application/x-www-form-urlencoded MIME类型。字段名称和值将先进行UTF-8进行编码,再根据RFC-3986进行URI编码。

2、@Multipart:作用于方法

使用该注解,表示请求体是多部分的,每个部分作为一个参数,且用Part注解声明。

3、@Streaming:作用于方法

未使用@Straming 注解,默认会把数据全部载入内存,之后通过流获取数据也是读取内存中数据,所以返回数据较大时,需要使用该注解。
处理返回Response的方法的响应体,用于下载大文件。

@Streaming
@GET
Call<ResponseBody> downloadFileWithDynamicUrlAsync(@Url String fileUrl)

三、注意事项:

  • 1、Map用来组合复杂的参数,并且对于FieldMap,HeaderMap,PartMap,QueryMap这四种作用方法的注解,其参数类型必须为Map实例,且key的类型必须为String类型,否则抛出异常。
  • 2、Query、QueryMap与Field、FieldMap功能一样,生成的数据形式一样;Query、QueryMap的数据体现在Url上;Field、FieldMap的数据是请求体
  • 3、{占位符}和PATH尽量只用在URL的path部分,url的参数使用Query、QueryMap代替,保证接口的简洁
  • 4、Query、Field、Part支持数据和实现了iterable接口的类型,如List、Set等,方便向后台传递数组,代码如下:
  • 5、以上部分注解真正的实现在ParameterHandler类中,每个注解的真正实现都是ParameterHandler类中的一个final类型的内部类,每个内部类都对各个注解的使用要求做了限制,比如参数是否可空、键和值是否可空等。
  • 6、@FormUrlEncoded 注解和@Multipart 注解不能同时使用,否则会抛出methodError(“Only one encoding annotation is allowed.”),可在ServiceMethod类中parseMethodAnnotation()方法中找到不能同时使用的具体原因。
  • 7、@Path 与@Url 注解不能同时使用,否则会抛出parameterError(p, "@Path parameters may not be used with @Url."),可在ServcieMethod类中parseParameterAnnotation()方法中找到不能同时使用的具体代码。其实原因也是很好理解:Path注解用于替换url中的参数,这就要求在使用path注解时,必须已经存在请求路径。不然没法替换路径中指定的参数。而@Url 注解是在参数中指定了请求路径的,这时候情定请求路径已经晚,path注解找不到请求路径,更别提更换请求路径了中的参数了。
  • 8 使用@Body 注解的参数不能使用form 或multi-part编码,即如果为方法使用了FormUrlEncoded或Multipart注解,则方法的参数中不能使用@Body 注解,否则会抛出异常parameterError(p, “@Body parameters cannot be used with form or multi-part encoding.”)

相关文章

网友评论

      本文标题:Retrofit(一)

      本文链接:https://www.haomeiwen.com/subject/rublxktx.html