1.注解簡介
Retrofit2.0是在okhttp的基礎上進行封裝的,網絡請求是通過okhttp實現的。Retrofit通過注解的方式,進行網絡請求描述。
共22個注解,根據功能大概分為三類:
請求方法類
GET、POST、PUT、DELETE、PATCH、HEAD、OPTIONS、HTTP
標記類
FormUrlEncoded
、Multipart
、Streaming
參數類
Headers
、Header
、Body
、Field
、FieldMap
、Part
、PartMap
、Query
、QueryMap
、Path
、URL
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 表單
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
- 作用于方法參數(形參)
Header
、Body
、Field
、FieldMap
、Part
、PartMap
、Query
、QueryMap
、Path
、URL
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等,方便向后臺傳遞數組。
內容主要轉自:https://blog.csdn.net/carson_ho/article/details/73732076
相關文章鏈接:
Retrofit 2.0快速集成