Retrofit官方使用文件
介紹
Retrofit 將你的HTTP API轉化為一個Java介面
public interface GitHubService {
@GET("users/{user}/repos")
Call<List<Repo>> listRepos(@Path("user") String user);
}
Retrofit 類會生成GitHubService介面的實現
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com/")
.build();
GitHubService service = retrofit.create(GitHubService.class);
生成的GitHubService能夠通過 call 傳送同步或一部的HTTP請求到遠端的伺服器上
Call<List<Repo>> repos = service.listRepos("octocat");
可以使用註解去描述一個HTTP請求:
- URL引數替換與查詢引數支援
- 將物件轉換為請求報文體(例如,JSON,protocol buffers)
- 多媒體支援和檔案上傳
API宣告
介面上的註解與其引數表明如何處理請求
請求方法
每一個方法必須有一個HTTP註解,這個註解需要提供請求方法和URL的相對路徑。 有五種內建的註解,分別為:GET, POST, PUT, DELETE與HEAD。請求的相對URL也是在註解中指定的。
@GET("users/list")
你可以在URL中指定查詢引數
@GET("users/list?sort=desc")
URL的操作
我們可以在方法中使用替換塊或引數來動態更新請求URL。替換塊是一個被{與}包圍著的字母或數字組成的字串。相應的引數必須使用 @Path 與相同的字串註釋起來。
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
GET中的查詢引數也應該這樣新增
@GET("group/{id}/users")
Call<List<User> > groupList(@Path("id") int groupId, @Query("sort") String sort);
更復雜的GET查詢引數可以使用Map進行新增
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
請求體
可以使用 加了 @Body 註解的物件作為一個HTTP請求的請求體
@POST("users/new")
Call<User> createUser(@Body User user);
如果你在建立Retrofit物件時指定了轉換器,則會使用該轉換器轉換物件為相應的請求體。如果沒有指定轉換器,則只能使用 RequestBody。
表單與多媒體資料
可以申明方法為傳送表單資料或多媒體資料
可以在方法上使用 @FormUrlEncoded 註解來發送表單資料。表單中要提交的鍵值對資料可以通過該方法引數中的 @Field 註解指定。
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
可以在方法上使用 @Multipart 註解來發送多媒體資料。要提交的資料可以通過方法引數中的 @Part 註解指定。
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
多媒體資料使用的轉換器也是Retrofit轉換器中的一個,當然,我們也可以自己實現RequestBody來處理資料的序列化。
請求頭的操作
你可以通過使用 @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);
注意:headers中的項不能被重寫覆蓋,所有擁有相同名字的headers都會被包含在請求中。
一個請求的header可以使用 @Header 註解進行動態的更新,當然,相關的引數也應該在 @Header 中提供。如果值為空的話,那個這個header就會被忽略。因此,值的 toString() 方法將會被呼叫,並且作為其header的值。
@GET("user")
Call<User> getUser(@Header("Authorization") String authorization)
與查詢引數類似,Map也可以被用在header中,用來指定複雜的header組合。
@GET("user")
Call<User> getUser(@HeaderMap Map<String, String> headers)
可以使用OkHttp攔截器指定需要新增到每個請求的請求頭。
同步請求 VS 非同步請求
Call 例項可以通過同步或非同步的方式執行。每個例項本來應當只能被呼叫一次,但呼叫 clone() 方法則會建立一個新的可用的例項。 在Android中,回撥函式將會通過主執行緒執行。但在JVM中,回撥函式將會在呼叫HTTP請求的同一個執行緒中執行。
Retrofit配置
Retrofit是將API介面轉換為可呼叫物件的類。預設情況下,Retrofit將為您的平臺提供合理的預設值,但它允許自定義。
轉換器
預設情況下,Retrofit只能將HTTP主體反序列化為OkHttp的ResponseBody型別,並且只能接受其RequestBody型別 @Body。 當然,也可以體檢其他型別的轉換器。這裡提供幾個可用作轉換器的比較流行序列化庫
- Gson: com.squareup.retrofit2:converter-gson
- Jackson: com.squareup.retrofit2:converter-jackson
- Moshi: com.squareup.retrofit2:converter-moshi
- Protobuf: com.squareup.retrofit2:converter-protobuf
- Wire: com.squareup.retrofit2:converter-wire
- Simple XML: com.squareup.retrofit2:converter-simplexml
- Scalars (primitives, boxed, and String): com.squareup.retrofit2:converter-scalars
下面是使用GsonConverterFactory該類生成GitHubService介面實現的示例,該介面使用Gson進行反序列化。
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.build();
GitHubService service = retrofit.create(GitHubService.class);
定製轉換器
如果您需要與使用 Retrofit 不支援開箱即用的內容格式的API(例如YAML,txt,自定義格式)進行通訊,或者您希望使用其他庫來實現現有格式,則可以輕鬆建立你自己的轉換器。建立一個擴充套件 Converter.Factory 的類,並在構建介面卡時傳入例項。
下載
MAVEN
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>(insert latest version)</version>
</dependency>
GRADLE
implementation 'com.squareup.retrofit2:retrofit:(insert latest version)'