1. 程式人生 > >Retrofit Url 配置

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

這個用法需要伺服器介面的配合。