引言
在日常業務開發中,我們時常需要使用一些其他公司的服務,呼叫第三方系統的介面,這時就會涉及到網路請求,通常我們可以使用HttpClient
,OkHttp
等框架去完成網路請求。隨著RESTful API的普及,一個高效、簡潔且易於維護的HTTP客戶端庫顯得尤為關鍵。而本文主要介紹一款強大的網路客戶端庫:Retrofit2
。
Retrofit2簡介
Retrofit2是什麼?
Retrofit2
是一個由Square公司精心打造並開源的Java
與Android
雙平臺適用的RESTful API
客戶端庫,其核心構建在效能卓越的OkHttp
庫之上。透過精巧的設計原理,Retrofit2
將原本複雜的HTTP網路請求過程高度抽象為直觀且型別安全的介面呼叫模式,從而極大地簡化了應用程式與後端API之間的互動邏輯。
開發者利用Retrofit2
能夠以註解驅動的方式來宣告和定義API介面,輕鬆指定HTTP方法、URL路徑以及請求引數等關鍵資訊,進而自動生成相應的請求實現程式碼。該框架不僅支援同步及非同步兩種呼叫方式,還內建了對JSON資料序列化和反序列化的自動化處理能力,這意味著無論是傳送請求還是解析響應,都能無縫轉換成或從對應的Java物件進行操作。
此外,Retrofit2
具備強大的擴充套件性,允許開發人員根據專案需求定製各種高階功能,如自定義轉換器以適應不同資料格式,新增攔截器以實現全域性請求/響應處理,以及整合多種認證機制,充分滿足現代應用程式中面對複雜網路環境的各種需求。
Retrofit2能做什麼?
Retrofit2
的主要功能包括:
-
型別安全API設計:
Retrofit2
賦予開發者以宣告式介面定義的方式來確保網路請求的型別安全性。這意味著透過在介面方法上使用註解來精確指定HTTP請求引數和響應資料結構,框架會自動進行型別校驗並確保資料在傳輸過程中嚴格符合預期型別,從而消除型別不匹配引發的執行時錯誤。 -
網路請求流程精簡:
Retrofit2
極大地簡化了發起網路請求的步驟。開發人員僅需專注於設計與後端服務互動的API介面及相應的HTTP
動作,框架會自動生成底層邏輯程式碼,無需手動編寫建立請求、設定Header
或解析響應內容等繁瑣環節,極大地提高了開發效率。 -
內建資料轉換機制:為便於資料處理,
Retrofit2
整合了多種資料轉換器(Converter
),能夠輕鬆地將從伺服器接收到的HTTP原始資料流轉換成Java物件,支援常見的資料格式如JSON
、XML
以及其他可透過擴充套件實現的格式,這使得資料模型與實際業務邏輯之間的對映變得直觀且易於管理。 -
非同步執行與回撥整合:針對移動應用中避免阻塞UI執行緒的需求,Retrofit2全面支援非同步網路請求。它允許開發者採用回撥函式或者結合RxJava等反應式程式設計庫來優雅地處理非同步任務,確保即便在網路請求執行期間也能保持流暢的使用者體驗和應用效能。
Retrofit2的優點
-
程式碼簡化與一致性:透過提供一種宣告式的方式來設計和實現網路請求介面,
Retrofit2
極大地減少了開發人員在處理網路通訊時所需編寫的重複性程式碼量。開發者僅需關注業務邏輯相關的API描述,無需手動構建和管理複雜的HTTP請求。 -
提升可讀性和維護性:框架強調清晰的結構和註解驅動的配置方式,使得網路請求邏輯更加直觀且易於理解,進而提高了程式碼的可讀性和維護性。開發者能夠快速識別並定位各個網路操作的意義和行為。
-
型別安全保證:透過整合型別安全的
API
設計,Retrofit2
消除了因引數拼寫錯誤或型別不匹配所引發的執行時異常風險。它確保了資料交換過程中引數型別的正確性,增強了應用的整體健壯性。 -
高效穩定整合:
Retrofit2
無縫整合了高效能的OkHttp
庫,充分利用了其在網路連線複用、快取策略、失敗重試等方面的效能優勢,從而有效提升了網路請求的執行效率及服務穩定性,為應用程式提供了更強大的網路支援基礎架構。
Retrofit2 VS HttpClient
-
現代化的 API 設計:
Retrofit2
使用現代程式設計風格,透過註解定義HTTP
請求介面,程式碼簡潔易讀。相比之下,HttpClient
需要手動構建Request
和處理響應,程式碼結構更為繁瑣。 -
自動轉換資料:
Retrofit2
提供了內建或自定義的資料轉換器,如GsonConverterFactory
,可以自動將JSON
或其他格式的資料轉換為Java
物件,簡化了資料的序列化和反序列化過程。HttpClient
則需要手動處理資料轉換,操作相對繁瑣。 -
非同步與同步支援:
Retrofit2
支援同步和非同步兩種網路請求方式,提供了基於Call
或Observable
等型別的非同步呼叫方式,方便結合RxJava
等響應式程式設計框架使用,極大地提升了使用者體驗和應用程式效能。HttpClient
在非同步支援方面較為侷限。 -
面向介面程式設計:
Retrofit2
透過定義服務介面來描述API端點,使得網路層與其他業務邏輯解耦,提高了程式碼組織性和可測試性。相比之下,HttpClient
直接操作HttpRequest
和HttpResponse
例項,耦合度較高。 -
相容性與效能:
官方不再推薦使用Apache HttpClient
,而OkHttp
(Retrofit2
底層依賴庫)經過持續最佳化,在效能、連線複用、快取策略以及對HTTP/2
協議的支援等方面表現更優。 -
易於擴充套件:
Retrofit2
可以很容易地新增攔截器(Interceptor
)進行諸如身份驗證、日誌記錄和重試機制等功能的擴充套件。雖然]HttpClient
的擴充套件性也很強,但需要更多手工編碼。 -
社群活躍與更新頻繁:
Retrofit2
和OkHttp
社群活躍,更新迭代較快,能快速跟進新的技術和最佳實踐,確保開發者能夠利用最新的技術改進和安全更新。
Retrofit2
在簡化RESTful API
客戶端開發、提高效率、易用性、可維護性以及對現代網路特性的支援上均優於舊版的 HttpClient
。
Retrofit2 VS OkHttp
-
API 介面定義簡潔明瞭:
Retrofit2 使用註解(Annotations)來描述 HTTP 請求方法、URL、引數等,開發者只需透過定義 Java 介面就能清晰地表達出網路呼叫的意圖。相比之下,OkHttp 需要開發者直接處理複雜的 HTTP 請求構建邏輯。 -
自動序列化與反序列化:
Retrofit2 提供了轉換器(Converter)支援,如 GsonConverterFactory、JacksonConverterFactory 等,能夠自動將 JSON 或其他格式的資料轉換為 Java 物件以及相反的操作,極大地簡化了資料處理過程。而 OkHttp 需要開發者手動處理資料轉換。 -
同步/非同步模式統一處理:
Retrofit2 不僅支援同步請求,還對非同步請求提供了統一的 Call 或 Observable 返回型別,方便在 Android 中進行非阻塞式程式設計,並且易於結合 RxJava 等響應式庫使用。相比之下,OkHttp 的非同步請求處理需要開發者自行管理。 -
豐富的註解體系:
Retrofit2 提供了多種註解以支援不同的請求型別(GET、POST、PUT、DELETE 等)、路徑引數、查詢引數、表單提交、檔案上傳、多部分請求等,可以靈活配置請求內容。而 OkHttp 的使用需要開發者手動構建請求引數和處理響應。 -
強大的擴充套件性:
Retrofit2 支援自定義攔截器(Interceptor),可以在請求前後新增額外的業務邏輯,如認證、日誌記錄、快取策略等。同時,可以自由配置 OkHttpClient 例項,充分利用 OkHttp 的所有特性,如連線池、重試機制、HTTP/2 支援等。相比之下,OkHttp 更專注於網路通訊的核心功能。 -
程式碼可讀性強:
Retrofit2 將網路請求抽象成一個服務介面的形式,使得程式碼更易於閱讀和維護,提高了整體專案的組織性和整潔度。相比之下,OkHttp 的使用需要開發者更多地關注底層的網路通訊細節。 -
降低耦合度:
使用 Retrofit2 可以將網路訪問層與應用的其他元件更好地解耦,使得業務邏輯程式碼更加關注於處理業務本身,而不是如何發起網路請求。相比之下,OkHttp 的使用需要開發者更多地處理網路請求的細節,耦合度較高。
雖然 OkHttp 是一個高效能的 HTTP 客戶端,專注於網路通訊的核心功能,但 Retrofit2 在此基礎上封裝了一層高階抽象,讓開發者能以宣告式的方式編寫網路請求程式碼,降低了複雜度並提升了開發效率。
Retrofit2使用
引入依賴
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>retrofit</artifactId>
<version>2.9.0</version>
</dependency>
<!-- 示例使用jackson的converter -->
<dependency>
<groupId>com.squareup.retrofit2</groupId>
<artifactId>converter-jackson</artifactId>
<version>2.9.0</version>
</dependency>
定義API介面
在Retrofit
框架中,構建與伺服器的通訊介面是透過定義清晰、結構化的API介面來實現的。這個過程涵蓋了詳細指定請求方式、路徑以及相關引數等關鍵資訊。具體來說,每個介面方法代表了一種特定的HTTP互動模式,明確指示了請求型別(如GET
、POST
、PUT
或DELETE
)和目標URL
路徑。
請求方法
在介面方法上應用諸如 @GET
、@POST
、@PUT
和@DELETE
等註解是為了精確對映到相應的HTTP動作。
@POST("user/add")
@GET("user/info/{id}")
// 也可以指定查詢引數
@GET("user/list?pageSize=50")
URL操作
利用@Path
、@Query
和@Body
註解能夠進一步細化介面描述,分別用於設定路徑中的動態變數、查詢字串引數以及HTTP
請求體內容。介面方法可以接受不同型別的引數,這些引數會根據註解型別被正確地插入到請求的不同部分。
使用@Path
註解的引數會在實際呼叫時將傳入值插入到URL
路徑中相應的位置
@GET("group/{id}/users")
Call<List<UserInfoResponse>> groupList(@Path("id") int groupId);
還可以透過@Query
引數新增查詢引數。
@GET("group/{id}/users")
Call<List<UserInfoResponse>> groupList(@Path("id") int groupId, @Query("pageSize") Integer pageSize);
對於複雜的查詢引數組合,可以使用Map
。
@GET("group/{id}/users")
Call<List<UserInfoResponse>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
請求體
對於請求物件,可以使用@Body
註解指定物件作為HTTP
請求體。@Body
註解通常用於指定將物件作為JSON
格式的資料傳輸到伺服器。當您在 Retrofit 介面方法中使用 @Body
註解時,Retrofit
將會使用內部的轉換器(如GsonConverter
或者 JacksonConverter
)將物件轉換為JSON
格式的字串,並將其作為請求的請求體傳送到伺服器。
通常情況下,@Body
註解用於POST
或者PUT
請求,其中請求的主體包含了要傳輸的物件的JSON
表示形式。
@POST("users/new")
Call<UserInfoResponse> createUser(@Body UserInfoRequest user);
通常情況下 @Body註解用於指定JSON格式的資料傳輸,但Retrofit並不會強制要求請求體的格式必須是JSON。您也可以使用其他格式的資料,例如XML或者純文字,只要在請求體中提供了正確的資料格式,並且伺服器能夠正確地解析這種格式的資料。
表單資料和Multipart請求
方法還可以宣告傳送表單資料和多部分請求資料
使用@FormUrlEncoded
,@Field
或者@FieldMap
將傳送表單資料。
@FormUrlEncoded
@POST("users/new")
Call<UserInfoResponse> createUser1(@Field("name") String name, @Field("passowrd") String password);
@FormUrlEncoded
@POST("users/new")
Call<UserInfoResponse> createUser2(@FieldMap Map<String, Object> paramMap);
同時他還支援傳送多部分請求,例如檔案上傳。在方法上使用@Multipart
註解用於傳送多部分請求,而引數要使用@Part
註解。在Retrofit
介面方法中使用@Multipart
註解時,Retrofit
將會使用multipart/form-data
格式來傳送請求,這種格式允許同時上傳文字資料和二進位制檔案資料。
@Multipart
@POST("user/image")
Call<UserInfoResponse> updateUser(@Part("image") RequestBody userImage, @Part("imageDesc") RequestBody imageDesc);
@Part
註解用於宣告每個部分的內容,其中可以是RequestBody
型別的文字或者二進位制資料,也可以是MultipartBody.Part
型別的檔案或者其他二進位制資料。這樣的話,就可以透過多個@Part
註解來宣告不同型別的部分,以滿足不同的上傳需求
Header資訊
使用@Headers
註解為方法設定靜態頭部。
@Headers({
"Accept: application/json, text/plain, */*",
"User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36",
"Cookie:xxxxxx"
})
@POST("users/new")
Call<UserInfoResponse> createUser(@Body UserInfoRequest user);
使用用@Header
或者HeaderMap
註解動態更新請求頭。必須提供相應的引數給@Header
。如果值為 null
,則頭部將被省略。否則,將對值呼叫toString
,並使用結果。
@POST("users/new")
Call<UserInfoResponse> createUser(@Header("Cookie") String cookie, @Body UserInfoRequest user);
@POST("users/new")
Call<UserInfoResponse> createUser2(@HeaderMap Map<String, String> headerMap, @Body UserInfoRequest user);
關於Header引數,我們還可以透過OkHttp的攔截器進行操作。
方法返回值
API介面方法通常返回 Call<T>
型別的物件,這裡的T代表期望從伺服器接收的資料型別。這種方式使得開發者能方便地利用 Retrofit 提供的回撥機制或其他響應式程式設計庫(如RxJava)來處理網路請求的結果,從而確保了對非同步操作的良好控制和管理。
public interface MyClientService {
@POST("test/add")
Call<TestResponse> addTest(@Body TestRequest testRequest);
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId);
}
建立Retrofit例項
Retrofit
框架的核心元件是Retrofit
例項。Retrofit
例項作為整個框架的心臟,不僅負責搭建網路請求所需的基礎設施,還承擔起發起請求、轉換資料和管理響應生命週期的任務。
Retrofit retrofit = new Retrofit.Builder()
// 設定 API 的基礎 URL
.baseUrl("http://localhost:8080/coderacademy/")
.addConverterFactory(JacksonConverterFactory.create())
.build();
baseUrl設定
其中baseUrl
用於指定請求伺服器的根地址或者API
的基礎路徑。Retrofit
會自動將baseUrl
和方法註解中的相對路徑結合起來生成實際請求的完整URL。例如對上述示例中:
public interface MyClientService {
@POST("test/add")
Call<TestResponse> addTest(@Body TestRequest testRequest);
}
最終的請求url為:localhost:8080/coderacademy/test/add
。
關於baseUrl
的設定有一些注意事項:
-
baseUrl設定必須以
/
結尾,否則彙報錯。
-
請求方法中的相對路徑(不以"/"開頭),將會正確附加在以斜槓結尾的 baseUrl 的路徑後面。這確保了正確的 URL 結果。如baseUrl
http://localhost:8080/coderacademy/
, 方法url為test/add
,則最終的路徑為:localhost:8080/coderacademy/test/add
。 -
請求方法中的絕對路徑(以"/"開頭),忽略
baseUrl
中的路徑元件,只保留host部分,最終的URL
將只包含baseUrl
的主機部分和方法的路徑。如baseUrlhttp://localhost:8080/coderacademy/
, 方法url為/test/add
,則最終的路徑為:localhost:8080/test/add
。 -
請求方法中的路徑可以是完整的
URL
,如果方法路徑是完整的URL,則會替換baseUrl
。如baseUrl為http://localhost:8080/coderacademy/
,而方法url為http://localhost:8081/coderacademy/test/add
,則最終的url為:http://localhost:8081/coderacademy/test/add
。
Converter設定
Retrofit
預設只能將HTTP
響應主體反序列化為OkHttp
的ResponseBody
型別,並且只能接受其RequestBody
型別用於@Body
註解。為了支援其他型別,可以新增轉換器。
官方提供了8種轉換器:
轉換器 | 功能 | 使用依賴 |
---|---|---|
Gson | 將 JSON 資料轉換為 Java 物件,以及將 Java 物件轉換為 JSON 資料。 | com.squareup.retrofit2:converter-gson |
Jackson | 將JSON資料轉換為 Java 物件,以及將 Java 物件轉換為 JSON 資料。 | com.squareup.retrofit2:converter-jackson |
Moshi | 將 JSON 資料轉換為 Java 物件,以及將 Java 物件轉換為 JSON 資料。 | com.squareup.retrofit2:converter-moshi |
Protobuf | 將 Protocol Buffers 資料轉換為 Java 物件,以及將 Java 物件轉換為 Protocol Buffers 資料。 | com.squareup.retrofit2:converter-protobuf |
Wire | 將 Wire 資料轉換為 Java 物件,以及將 Java 物件轉換為 Wire 資料。 | com.squareup.retrofit2:converter-wire |
Simple XML | 將 XML 資料轉換為 Java 物件,以及將 Java 物件轉換為 XML 資料。 | com.squareup.retrofit2:converter-simplexml |
JAXB | 將 XML 資料轉換為 Java 物件,以及將 Java 物件轉換為 XML 資料。 | com.squareup.retrofit2:converter-jaxb |
Scalars | 將原始型別、包裝型別和字串轉換為 RequestBody,以及將 ResponseBody 轉換為原始型別、包裝型別和字串。 | com.squareup.retrofit2:converter-scalars |
除了官方提供的這幾種轉換器以外,如果使用了Retrofit 預設不支援的內容格式的API 進行通訊(例如YAML 、TXT 、自定義格式),或者使用不同的庫來實現現有格式(請求與響應是不同的格式),我們也可以實現自定義轉換器。 |
除此之外Retrofit
還可以跟OkHttpClient
搭配使用,實現其高階功能,透過 OkHttpClient
,您可以實現諸如網路連線池、超時設定、重試機制、攔截器等高階功能。而Retrofit
則提供了簡化的API
,使得使用這些高階功能變得更加方便。
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS) // 設定連線超時時間
.readTimeout(30, TimeUnit.SECONDS) // 設定讀取超時時間
.writeTimeout(30, TimeUnit.SECONDS) // 設定寫入超時時間
.addInterceptor(new LoggingInterceptor()) // 新增日誌攔截器
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://localhost:8080/coderacademy/")
.client(okHttpClient) // 設定自定義的 OkHttpClient
.addConverterFactory(GsonConverterFactory.create())
.build();
建立請求介面例項,發起請求
在建立完Retrofit
例項之後,接下來就需要透過呼叫Retrofit
例項的create()
方法來建立API
介面的例項。然後就可以使用該例項呼叫定義在介面中的方法來發起網路請求。
MyClientService myClientService = retrofit.create(MyClientService.class);
TestRequest testRequest = new TestRequest();
testRequest.setName("碼農Academy");
testRequest.setPassword("12131");
// 發起請求
Call<TestResponse> call = myClientService.addTest(testRequest);
try {
Response<TestResponse> response = call.execute();
System.out.println("是否請求成功:"+response.isSuccessful());
System.out.println("響應:"+ response.toString());
TestResponse testResponse = response.body();
System.out.println("請求結果:"+ testResponse.toString());
}catch (Exception e){
e.printStackTrace();
}
在Retrofit
中,Call
物件代表了一個待執行的網路請求。它是一個表示單個非同步或同步執行的請求的物件。Call
介面定義了執行網路請求和處理響應的方法。Call
介面的泛型型別參數列示了該網路請求的響應型別。例如,Call<TestResponse>
表示該網路請求的響應是一個TestResponse
物件響應。
execute()
方法用於同步執行網路請求,並返回一個Response
物件。當呼叫execute()
方法時,請求將立即發出,當前執行緒將被阻塞直到請求完成並返回響應。Response
物件包含了網路請求的響應資料,可以透過呼叫body()
方法來獲取響應主體。
另外,還可以使用Call
物件來發起非同步網路請求。非同步請求允許您在發出請求後繼續執行其他程式碼,而不必等待網路請求完成。當請求完成後,Retrofit
將在後臺執行緒上呼叫您提供的回撥方法,以處理響應資料。
Call<TestResponse> call = myClientService.addTest(testRequest);
try {
call.enqueue(new Callback<TestResponse>() {
@Override
public void onResponse(Call<TestResponse> call, Response<TestResponse> response) {
System.out.println("是否請求成功:"+response.isSuccessful());
System.out.println("響應:"+ response.toString());
TestResponse testResponse = response.body();
System.out.println("請求結果:"+ testResponse.toString());
}
@Override
public void onFailure(Call<TestResponse> call, Throwable t) {
// 請求失敗結果
}
});
}catch (Exception e){
e.printStackTrace();
}
非同步請求時,需要實現Callback
介面,該介面定義了處理成功和失敗響應的方法。在 onResponse
方法中處理成功響應,在onFailure
方法中處理失敗響應。
然後使用Call
物件的enqueue()
方法來執行非同步網路請求,並傳入Callback
。Retrofit
將在後臺執行緒上執行網路請求,並在請求完成後呼叫相應的回撥方法。
到此一個使用Retrofit2
發起請求的功能就完成了。接下來我們看一下Retrofit2
的一些高階功能。
Retrofit2的高階功能
攔截器
Retrofit
的高階功能通常需要與OkHttpClient
結合使用才能實現。OkHttpClient
是一個強大的HTTP
客戶端庫,Retrofit
是基於它構建的,並且Retrofit
預設使用 OkHttpClient
作為其底層的網路請求庫。
透過OkHttpClient
,您可以實現諸如網路連線池、超時設定、重試機制、攔截器等高階功能。而Retrofit
則提供了簡化的API
,使得使用這些高階功能變得更加方便。
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS) // 設定連線超時時間
.readTimeout(30, TimeUnit.SECONDS) // 設定讀取超時時間
.writeTimeout(30, TimeUnit.SECONDS) // 設定寫入超時時間
.addInterceptor(new LoggingInterceptor()) // 新增日誌攔截器
.build();
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://localhost:8080/coderacademy/")
.client(okHttpClient) // 設定自定義的 OkHttpClient
.addConverterFactory(GsonConverterFactory.create())
.build();
對於攔截器,在實際開發中有較多需要使用的場景,比如第三方服務需要使用一些簽名驗證手段,請求資料進行加密等,我們都可以統一在攔截器中進行處理。自定義攔截器,我們需要實現Interceptor
介面,實現intercept()
方法。
@Slf4j
public class MyAuthInterceptor implements Interceptor {
@NotNull
@Override
public Response intercept(@NotNull Chain chain) throws IOException {
String appKey = "MyKey";
String appToken = "MyToken";
Request request = chain.request();
Request.Builder builder = request.newBuilder();
builder.addHeader("Api-Key", appKey).addHeader("Api-Secret", appToken);
request = builder.build();
return chain.proceed(request);
}
}
傳入攔截器:
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(30, TimeUnit.SECONDS) // 設定連線超時時間
.readTimeout(30, TimeUnit.SECONDS) // 設定讀取超時時間
.writeTimeout(30, TimeUnit.SECONDS) // 設定寫入超時時間
.addInterceptor(new LoggingInterceptor()) // 新增日誌攔截器
.addInterceptor(new MyAuthInterceptor())
.build();
轉換器
前面內容已經提到對於轉換器,出了Retrofit2
提供的8種轉換器以外,有些特別的請求體這幾種轉換器不能滿足,此時,我們可以自定義轉換器。需要繼承Converter.Factory
類,重寫requestBodyConverter
與reponseBodyConverter
方法即可。
public class CustomBodyConverterFactory extends Converter.Factory {
@Nullable
@Override
public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations, Retrofit retrofit) {
return new CustomResponseBodyConverter(type);
}
@Nullable
@Override
public Converter<?, RequestBody> requestBodyConverter(Type type, Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
return new CustomRequestBodyConverter(type);
}
}
然後我們在分別實現CustomResponseBodyConverter
以及CustomRequestBodyConverter
,實現請求與響應不同的轉換器。
@Slf4j
public class CustomRequestBodyConverter implements Converter<CustomRequest, RequestBody> {
private final ObjectMapper objectMapper;
public CustomRequestBodyConverter() {
this.objectMapper = new ObjectMapper(new JsonFactoryBuilder().build());
this.objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
this.objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
this.objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
}
@Nullable
@Override
public RequestBody convert(CustomRequest CustomRequest) throws IOException {
// 具體轉換邏輯
}
}
/**
*響應轉換器
*/
public class CustomResponseBodyConverter implements Converter<ResponseBody, Object> {
private final Type type;
/**
* 物件對映器
*/
private final Gson gson;
public CustomResponseBodyConverter(Type type) {
this.type = type;
GsonBuilder gsonBuilder = new GsonBuilder();
this.gson = gsonBuilder.create();
}
@Override
public Object convert(ResponseBody value) throws IOException {
// 具體處理邏輯
}
}
使用自定義轉換器
Retrofit retrofit = new Retrofit.Builder()
.baseUrl("http://localhost:8080/coderacademy/")
.client(okHttpClient) // 設定自定義的 OkHttpClient
.addConverterFactory(new CustomBodyConverterFactory())
.build();
總結
本文深入介紹了Retrofit2
,這是由Square
公司開源的一款面向Java
和Android
平臺的RESTful API
客戶端庫。基於強大的OkHttp
網路庫構建,Retrofit2
透過優雅的設計理念,將複雜的HTTP
請求抽象為型別安全且易於理解的介面呼叫。
在使用Retrofit2
時,開發者可以利用註解來定義API
介面以及配置請求方法、URL
路徑、引數等資訊,大大簡化了網路通訊實現過程,提高了程式碼可讀性和維護性。同時,Retrofit2
內建了多種資料轉換器(如GsonConverterFactory
),支援JSON
以及其他格式的資料自動序列化與反序列化,極大地降低了開發成本。
Retrofit2
不僅支援同步和非同步兩種請求模式,還提供了豐富的擴充套件機制,包括自定義轉換器以適應不同資料格式,新增攔截器處理全域性請求/響應邏輯,以及整合各種認證方式,滿足複雜網路環境下的各類需求。
此外,本文還闡述瞭如何建立和配置Retrofit
例項,給出了具體的使用示例,並深入探討了如何利用高階功能如自定義轉換器、攔截器以及進行身份驗證等,進一步展示了 Retrofit2
在實際專案中的強大靈活性和實用性。透過本文的學習,讀者將能夠更加熟練地使用Retrofit2
開發出高效、可靠的網路請求功能。
本文已收錄於我的個人部落格:碼農Academy的部落格,專注分享Java技術乾貨,包括Java基礎、Spring Boot、Spring Cloud、Mysql、Redis、Elasticsearch、中介軟體、架構設計、面試題、程式設計師攻略等