继续上一篇笔记,我们继续记录一下Retrofit2对象创建之后,我们就可以创建网络请求对应的interface
了。
使用注解定义网络请求API
public interface WeatherService {
@GET("weather_mini")
Call<WeatherBean> getWeatherInfo(@Query("city") String city);
}
上面的代码使用了@GET
注解定义了一个GET
请求。那么Retrofit2还支持哪些注解呢?
上面的表格就是retrofit2所支持的部分注解,我们一一了解一下。
首先是
@GET
注解,这个注解是用来声明一个GET请求的。@GET("users/list")
这是一个GET注解的简单使用方法,注解的参数"users/list"会和声明Retrofit2对象时设置的根URL拼接,我们还可以添加参数。
@GET("users/list?sort=desc")
当然也可以用变量
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
这其实这也引入了另一个注解@Path
,它会替换URL中的用花括号包起来的变量。使用方法如上面代码,URL中的‘id’会被替换成groupList方法的入参groupId。
当然要动态加参数也是可以的。
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
@Path
注解的使用方法同上,我们关注一下@Query
注解,上面代码生成的url会是这样的group/groupId对应的值/users?sort=sort对应的值
这样的url。这样我们就可以在URL中添加参数了,如果我们要添加多个参数的话还可以使用@QueryMap
这个注解。
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
可以看到@QueryMap
这个注解对应的是一个Map数据类型,它的的泛型是Map<String,String>
所以它的key和value都是String类型的,它的key和Value在URL中的对应关系如下group/groupId/users?key=value
所以理解起来也比较容易。
好我们再来看一下Retrofit2中的POST请求对应的注解@POST
。
@POST("users/new")
Call<User> createUser(@Body User user);
上面的代码中使用了两个注解,我们先看@POST
注解,它的参数和@GET
注解类似都代表拼接的URL,再看@Body
注解,上面的代码中使用的是一个User实体bean,这个时候就需要使用我们上一个笔记中的转换器Converter
设置对应的转换器就可以把实体bean转换成Converter
对应的数据类型,比如这里我们使用一个Gson的转换器,在这里我们使用@Body
注解注解的时候user
对象就会被转换成json字符串被放入到post请求中,如果没有设置任务Converter
这个地方只能是RequestBody
类型的参数。具体RequestBody
类型的使用方法我会在以后的笔记中介绍。
HTTP请求还可以有FROM表单的提交,要使用FROM表单提交我们可以这样做。
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
@FormUrlEncoded
注解表示POST请求携带了FROM表单,@Field
注解对应FROM表单中的每个属性值,比如@Field("first_name") String first
代表FROM表单中的first_name
属性的值为first
。当然我们也可以批量添加属性值,对应的注解为@FieldMap
,它的用法和@QueryMap
一样大家可以去上面参考一下。
还有一个注解@Url
,这个注解是在@GET
和@POST
没有设置URL时必须使用的。
@GET //当有URL注解时,这里的URL就省略了
Call<ResponseBody> query(@Url String url, @Query("showAll") boolean showAll);
@Url
注解支持的类型有okhttp3.HttpUrl
,String
, java.net.URI
, android.net.Uri
几种。
再介绍一个注解@HTTP
,它的用法如下:
public interface BlogService {
/**
* method 表示请的方法,不区分大小写
* path表示路径
* hasBody表示是否有请求体
*/
@HTTP(method = "get", path = "blog/{id}", hasBody = false)
Call<ResponseBody> getFirstBlog(@Path("id") int id);
}
这个@HTTP
注解可以包含很多注解的功能,GET
,POST
,PATH
,HEAD
等等。
如果我们要在HTTP请求的header中加入参数就需要@Header
和@Headers
两个注解。
public interface BlogService {
@GET("/headers?showAll=true")
@Headers({"CustomHeader1: customHeaderValue1", "CustomHeader2: customHeaderValue2"})
Call<ResponseBody> testHeader(@Header("CustomHeader3") String customHeaderValue3);
}
相信大家看到代码也就知道了这两个注解的使用方法了。
还有一种情况是文件上传,先看代码。
/**
* @Part后面支持三种类型,RequestBody、okhttp3.MultipartBody.Part、任意类型
* 除 okhttp3.MultipartBody.Part以外,其它类型都必须带上表单字段(okhttp3.MultipartBody.Part中已经包含了表单字段的信息),
*/
@POST("/form")
@Multipart
Call<ResponseBody> fileUpload1(@Part("name") RequestBody name,@Part MultipartBody.Part file);
/**
* PartMap 注解支持一个Map作为参数,支持RequestBody类型,
* 如果有其它的类型,会被retrofit2.Converter转换,如使用com.google.gson.Gson的retrofit2.converter.gson.GsonRequestBodyConverter
* 所以MultipartBody.Part就不适用了,所以文件只能用MultipartBody.Part
*/
@POST("/form")
@Multipart
Call<ResponseBody> fileUpload2(@PartMap Map<String, RequestBody> args, @Part MultipartBody.Part file);
上面代码有三个新注解@Multipart
和@Part
以及@PartMap
,@Multipart
注解表示请求体是一个支持文件上传的FROM表单,@Part
代表表单的属性,@Part
后面支持三种类型,RequestBody、okhttp3.MultipartBody.Part、任意类型。除 okhttp3.MultipartBody.Part以外,其它类型都必须带上表单字段,okhttp3.MultipartBody.Part对应的是文件流。@PartMap
注解和上面的类似,是一个集合注解。要是使用文件上传需要使用如下方法。
MediaType textType = MediaType.parse("text/plain");
RequestBody name = RequestBody.create(textType, "name");
RequestBody file = RequestBody.create(MediaType.parse("application/octet-stream"), "这里是模拟文件的内容");
首先我们要定义一下part的类型,MediaType textType = MediaType.parse("text/plain");
这个声明的是文本类型,而RequestBody file = RequestBody.create(MediaType.parse("application/octet-stream"), "这里是模拟文件的内容");
这里声明的就是二进制类型,我们来看一下RequestBody
类的方法。
重点看
create
方法的几个重载,根据参数的不同我们可以传入文本、byte数组、文件对象,这基本满足了我们的需要。