Retrofit Url 配置
如果你用post請求進行提交資料(比如使用者註冊、登陸等表單類請求),引數型別一定要用準確,是Field,如果選擇了Query,而除錯過程沒有發現這個問題,相信我你會發瘋的。
@FormUrlEncoded @POST("/some/endpoint") Call<Response> register(@Field("name") String name); @FormUrlEncoded @POST("/some/endpoint") Call<SomeResponse> someEndpoint(@FieldMap Map<String, String> names);
@FormUrlEncoded必須帶上,防止出現亂碼。
Retrofit 支援的協議包括 GET/POST/PUT/DELETE/HEAD/PATCH,當然你也可以直接用 HTTP 來自定義請求。這些協議均以註解的形式進行配置,比如我們已經見過 GET 的用法:
public interface IFamousInfo { @GET("/avatardata/mingrenmingyan/lookup") Call<FamousInfo> getFamousResult(@Header("apiKey") String apiKey, @Query("keyword") String keyword, @Query("page") int page, @Query("rows") int rows); }
又如下面的:
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
- 1
- 2
這些註解都有一個引數 value,用來配置其路徑,比如示例中的 users/{user}/repos,我們還注意到在構造 Retrofit 之時我們還傳入了一個 baseUrl(“https://api.github.com/“),請求的完整 Url 就是通過 baseUrl 與註解的 value(下面稱 “path“ ) 整合起來的,具體整合的規則如下:
建議採用第二種方式來配置,並儘量使用同一種路徑形式。如果你在程式碼裡面混合採用了多種配置形式,分分鐘能出一堆 bug。
引數型別
發請求時,需要傳入引數,Retrofit 通過註解的形式令 Http 請求的引數變得更加直接,而且型別安全。
Query & QueryMap(GET請求)
@GET("/list")
Call<ResponseBody> list(@Query("page") int page);
Query 其實就是 Url 中 ‘?’ 後面的 key-value,比如:
這裡的 cate=android 就是一個 Query,而我們在配置它的時候只需要在介面方法中增加一個引數,即可:
interface PrintlnServer{
@GET("/")
Call<String> cate(@Query("cate") String cate);
}
如果有很多個Query,這麼一個個寫豈不是很累?而且根據不同的情況,有些欄位可能不傳,這與方法的引數要求顯然也不相符。這時,容量更大的QueryMap 就是你最好的選擇。
Field & FieldMap(POST請求) 其實我們用 POST 的場景相對較多,絕大多數的服務端介面都需要做加密、鑑權和校驗,GET 顯然不能很好的滿足這個需求。使用 POST 提交表單的場景就更是剛需了,怎麼做呢?
@FormUrlEncoded
@POST("/")
Call<ResponseBody> submit(
@Field("name") String name,
@Field("occupation") String occupation);
其實也很簡單,我們只需要定義上面的介面就可以了,我們用 Field 聲明瞭表單的項,這樣提交表單就跟普通的函式呼叫一樣簡單直接了。
與Query一樣,如果你有很多Field引數,不要怕,趕緊試試FieldMap吧。
Part & PartMap(POST請求) 這個是用來上傳檔案的。有了 Retrofit,媽媽再也不用擔心檔案上傳費勁了~~~
public interface FileUploadService {
@Multipart
@POST("upload")
Call<ResponseBody> upload(@Part("description") RequestBody description,
@Part MultipartBody.Part file);
}
如果你需要上傳檔案,和我們前面的做法類似,定義一個介面方法,需要注意的是,這個方法不再有 @FormUrlEncoded 這個註解,而換成了 @Multipart,後面只需要在引數中增加 Part 就可以了。也許你會問,這裡的 Part 和 Field 究竟有什麼區別,其實從功能上講,無非就是客戶端向服務端發起請求攜帶引數的方式不同,並且前者可以攜帶的引數型別更加豐富,包括資料流。
也正是因為這一點,我們可以通過這種方式來上傳檔案,下面我們就給出這個介面的使用方法:
在實驗時,我上傳了一個只包含一行文字的檔案:
Visit me: http://www.println.net
那麼我們去服務端看下我們的請求是什麼樣的:
HEADERS
FORM/POST PARAMETERS
description: This is a description
RAW BODY
最後放出一個絕招。
Retrofit2之“多個同名的查詢引數”
如下連結:
https://api.stay4it.com/tasks?id=123
這個API例子只是返回id=123單個任務的response。
public interface TaskService {
@GET("/tasks")
Call<Task> getTask(@Query("id") long taskId);
}
那麼問題來了,如果有多個相同的id引數,怎麼解決呢?
Multiple Query Parameters
我們需要請求的url就像下面那樣
我們預期返回的response是一個以url的ids=[123, 124, 125]為查詢引數任務列表。
Retrofit通過提供一個ids的列表作為一個引數來執行一個含有多個同名引數的請求。Retrofit會一一對應給定的列表和多個同名引數。
public interface TaskService {
@GET("/tasks")
Call<List<Task>> getTask(@Query("id") List<Long> taskIds);
}
@Body
這個用法需要伺服器介面的配合。