Retrofit2.0 注解简介

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_34895720/article/details/101380818

1.注解简介

Retrofit2.0是在okhttp的基础上进行封装的,网络请求是通过okhttp实现的。Retrofit通过注解的方式,进行网络请求描述。

共22个注解,根据功能大概分为三类:

  • 请求方法类
    GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、HTTP

  • 标记类
    FormUrlEncodedMultipartStreaming

  • 参数类
    HeadersHeaderBodyFieldFieldMapPartPartMapQueryQueryMapPathURL

1.1请求方法类

GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、HTTP共8个。

分别对应 HTTP 的请求方法;(HTTP除外)
接收一个字符串表示接口 path ,与 baseUrl 组成完整的 Url;
可以不指定,结合 @Url 注解使用;
url 中可以使用变量,如 {id} ,并使用 @Path("id") 注解为 {id} 提供值。

目前也只用到了GET和POST。如:

    @GET("new/{id}")
    Call<ResponseBody> getNew(@Path("id") int id);

这里说名下HTTP

可用于替代以上 7 个,及其他扩展方法;
有 3 个属性:method、path、hasBody

public interface BlogService{
    /**
    * method  请求方法,不区分大小写
    * path    路径
    * hasBody 是否有请求体
    */
    @HTTP(method = "get", path = "new/{id}", hasBody = false)
    Call<ResponseBody> getNew(@Path("id") int id);
}

1.2 标记类

  • 表单请求:
    FormUrlEncoded
    Multipart
  • 标记
    Streaming

FormUrlEncoded
请求体是 From 表单

扫描二维码关注公众号,回复: 7568281 查看本文章
Content-Type:application/x-www-form-urlencoded

Multipart
请求体是支持文件上传的 From 表单

#上传文件使用:Content-Type:multipart/form-data
//传单个文件
@Multipart
@POST("v1/create")
Call<ResponseBody> create(@Part("pictureName") RequestBody pictureName,  @Part MultipartBody.Part picture)

RequestBody pictureNameBody = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), "pictureName");
File picture= new File(path);
RequestBody requestFile = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), picture);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part picturePart = MultipartBody.Part.createFormData("picture", picture.getName(), requestFile);
//调接口
create(pictureNameBody, picturePart);

//传多个文件
@Multipart
@POST("v1/create")
Call<ResponseBody> create(@Part("pictureName") RequestBody pictureName,   @PartMap Map<String, RequestBody> map)

RequestBody pictureNameBody = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), "pictureName");
File picture= new File(path);
RequestBody requestFile = RequestBody.create(MediaType.parse(AppConstants.CONTENT_TYPE_FILE), picture);
Map<String, RequestBody> params = new HashMap<>();
params.put("picture\"; filename=\"" + picture.getName() + "", requestFile);
//调接口
create(pictureNameBody, params);

标记
Streaming
响应体的数据用流的形式返回
未使用该注解,默认会把数据全部载入内存,之后通过流获取数据也是读取内存中数据,所以返回数据较大时,需要使用该注解。

1.3 参数类

  • 作用于方法
    Headers
  • 作用于方法参数(形参)
    HeaderBodyFieldFieldMapPartPartMapQueryQueryMapPathURL

Headers

使用 @Headers 注解设置固定的请求头,所有请求头不会相互覆盖,即使名字相同。

@Headers("Cache-Control: max-age=640000")
@GET("widget/list")
Call<List<Widget>> widgetList();

@Headers({ "Accept: application/vnd.github.v3.full+json","User-Agent: Retrofit-Sample-App"})
@GET("users/{username}")Call<User> getUser(@Path("username") String username);

@Header

使用 @Header 注解动态更新请求头,匹配的参数必须提供给 @Header ,若参数值为 null ,这个头会被省略,否则,会使用参数值的 toString 方法的返回值。

@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)

@Body

非表单请求体;
使用 @Body 注解,指定一个对象作为 request body 。
作用:以 Post方式 传递 自定义数据类型 给服务器
注意:如果提交的是一个Map,那么作用相当于 @Field

@POST("users/new")
Call<User> createUser(@Body User user);

@Field

表单字段
作用:发送 Post请求 时提交请求的表单字段
具体使用:与 @FormUrlEncoded 注解配合使用

@POST("/form")
@FormUrlEncoded
Call<ResponseBody> testFormUrlEncoded1(@Field("username") String name, @Field("age") int age);

@FieldMap

表单字段,与 Field、FormUrlEncoded 配合;接受 Map<String, String> 类型,非 String 类型会调用 toString() 方法

/**
  * Map的key作为表单的键
  */
@POST("/form")
@FormUrlEncoded
Call<ResponseBody> testFormUrlEncoded2(@FieldMap Map<String, Object> map);

@Part@PartMap

post请求时,提交请求的表单字段,与 @ Multipart注解 配合。
和@Field的区别:功能相同,但携带的参数类型更加丰富,包括数据流,所以适用于 有文件上传 的场景

/**
  * {@link Part} 后面支持三种类型,{@link RequestBody}、{@link okhttp3.MultipartBody.Part} 、任意类型
  * 除 {@link okhttp3.MultipartBody.Part} 以外,其它类型都必须带上表单字段({@link okhttp3.MultipartBody.Part} 中已经包含了表单字段的信息),
  */
@POST("/form")
@Multipart
Call<ResponseBody> testFileUpload1(@Part("name") RequestBody name, @Part("age") RequestBody age, @Part MultipartBody.Part file);

/**
  * PartMap 注解支持一个Map作为参数,支持 {@link RequestBody } 类型,
  * 如果有其它的类型,会被{@link retrofit2.Converter}转换,如后面会介绍的 使用{@link com.google.gson.Gson} 的 {@link retrofit2.converter.gson.GsonRequestBodyConverter}
  * 所以{@link MultipartBody.Part} 就不适用了,所以文件只能用<b> @Part MultipartBody.Part </b>
         */
@POST("/form")
@Multipart
Call<ResponseBody> testFileUpload2(@PartMap Map<String, RequestBody> args, @Part MultipartBody.Part file);

@POST("/form")
@Multipart
Call<ResponseBody> testFileUpload3(@PartMap Map<String, RequestBody> args);

        // 具体使用
        MediaType textType = MediaType.parse("text/plain");
        RequestBody name = RequestBody.create(textType, "Carson");
        RequestBody age = RequestBody.create(textType, "24");
        RequestBody file = RequestBody.create(MediaType.parse("application/octet-stream"), "这里是模拟文件的内容");

        // @Part
        MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", "test.txt", file);
        Call<ResponseBody> call3 = service.testFileUpload1(name, age, filePart);
        ResponseBodyPrinter.printResponseBody(call3);

        // @PartMap
        // 实现和上面同样的效果
        Map<String, RequestBody> fileUpload2Args = new HashMap<>();
        fileUpload2Args.put("name", name);
        fileUpload2Args.put("age", age);
        //这里并不会被当成文件,因为没有文件名(包含在Content-Disposition请求头中),但上面的 filePart 有
        //fileUpload2Args.put("file", file);
        Call<ResponseBody> call4 = service.testFileUpload2(fileUpload2Args, filePart); //单独处理文件
        ResponseBodyPrinter.printResponseBody(call4);

@Path

作用:URL地址的缺省值

@GET("users/{user}/repos")
Call<ResponseBody>  getBlog(@Path("user") String user );

@Query@QueryMap

作用:用于 @GET 方法的查询参数(Query = Url 中 ‘?’ 后面的 key-value)

@GET("/")    
Call<String> cate(@Query("cate") String cate);

@GET("/")    
Call<String> cate(@QueryMap Map map);

@Url

作用:直接传入一个请求的 URL变量 用于URL设置

@GET
Call<ResponseBody> testUrlAndQuery(@Url String url, @Query("showAll") boolean showAll);

参数注解小结:

  • Map 用来组合复杂的参数;
  • Query、QueryMap 与 Field、FieldMap 功能一样,生成的数据形式一样;
    Query、QueryMap 的数据体现在 Url 上;
    Field、FieldMap 的数据是请求体;
  • {占位符}和 PATH 尽量只用在URL的 path 部分,url 中的参数使用 Query、QueryMap 代替,保证接口的简洁;
  • Query、Field、Part 支持数组和实现了 Iterable 接口的类型, 如 List、Set等,方便向后台传递数组。

猜你喜欢

转载自blog.csdn.net/qq_34895720/article/details/101380818