1. 程式人生 > >Retrofit官方使用文件

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)'