前言
在項目開發中,後端會經常去請求一些已經開發好的服務接口擷取資料。直接使用okhttp、httpClient發起http請求,既繁瑣又不友善統一管理。在這裡推薦一個适用于Spring Boot項目的輕量級HTTP用戶端架構retrofit,使用非常簡單友善。retrofit是一款類型安全的HTTP用戶端,其最大的特性的是支援通過接口的方式發起HTTP請求 。
準備
使用前期講到的Spring Boot可視化接口開發工具magic-api部署兩個http服務接口,不知道可視化接口開發工具的可以翻看前期的文章,這裡不再過多說明。
get接口
http://127.0.0.1:9999/user/select?id=15
post接口
http://127.0.0.1:9999/user/update
{
"id":15,
"name": "九天銀河聊程式設計",
"age": 35,
"address": "天津"
}
retrofit開發
引入依賴
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
配置檔案
server:
port: 8080
retrofit:
global-log:
enable: true
log-level: info
HttpClient:
BaseUrl: "http://127.0.0.1:9999/"
編寫參數實體
根據接口的輸入參數編寫相關實體,代碼略!
http接口定義
@RetrofitClient(baseUrl = "${HttpClient.BaseUrl}")
public interface Api {
@GET("user/select")
Result1 getUser(@Query("id") Integer id);
@POST("user/update")
Result2 updateUser(@Body User user);
}
使用
@RestController
@RequestMapping("user/")
public class RetrofitController {
@Autowired
private Api api;
@GetMapping("/select")
public User[] select() {
Result1 result = api.getUser(15);
return result.getData();
}
@GetMapping("/update")
public String update() {
User user = new User();
user.setId(15);
user.setAge(35);
user.setName("九天銀河聊程式設計");
user.setAddress("天津");
Result2 result = api.updateUser(user);
return result.getData();
}
}
調用服務
控制台輸出:
控制台輸出:
大功告成,是不是很簡單?
常用注解說明
方法注解
@GET | GET請求 |
@POST | POST請求 |
@HTTP | 作用于方法,用于發送一個 自定義的HTTP請求 |
标記注解
@FormUrlEncoded
請求體是 From 表單 @POST比起@GET多了一個@FromUrlEncoded的注解。
@Multipart
請求體是支援檔案上傳的 From 表單
@Streaming
響應體的資料用流的形式傳回,未使用該注解,預設會把資料全部載入記憶體,之後通過流擷取資料也是讀取記憶體中資料,是以傳回資料較大時,需要使用該注解。
參數注解
@Query
用于Get請求資料,用于拼接在拼接在Url路徑後面的查詢參數,一個@Query相當于拼接一個參數,多個參數中間用,隔開
@Body
非表單請求體,是結合post請求的
@Field
表單字段,@Field的用法類似于@Query,不同的是@Field主要用于Post請求資料。
@Part
表單字段,與 PartMap 配合,适合檔案上傳情況
@PartMap
表單字段,與 Part 配合,适合檔案上傳情況;預設接受 Map<String, RequestBody> 類型,非 RequestBody 會通過 Converter 轉換
其它注解
@Url
@Url是動态的Url請求資料的注解。需要注意的是使用@Url時,path對應的路徑不能包含”/”,不然每個加到host Url後面的東西都會被省略掉。千萬注意了
@Path
@Path主要用于Get請求,用于替換Url路徑中的變量字元。
踩坑記錄
當POST請求時,@FormUrlEncoded和@Field簡單的表單鍵值對。兩個需要結合使用,否則會報錯。
其它調用例子
RestFul方式請求
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @Query("sort") String sort);
map作為請求體
@GET("group/{id}/users")
Call<List<User>> groupList(@Path("id") int groupId, @QueryMap Map<String, String> options);
表單送出
@FormUrlEncoded
@POST("user/edit")
Call<User> updateUser(@Field("first_name") String first, @Field("last_name") String last);
Multipart請求
@Multipart
@PUT("user/photo")
Call<User> updateUser(@Part("photo") RequestBody photo, @Part("description") RequestBody description);
進階應用
注解式攔截器
對http請求執行統一的攔截處理邏輯,基于url路徑的比對攔截 。使用的步驟主要分為2步:
- 繼承BasePathMatchInterceptor編寫攔截處理器;
- 接口上使用@Intercept進行标注。如需配置多個攔截器,在接口上标注多個@Intercept注解即可!
擴充注解式攔截器
對攔截注解動态傳入一些參數,然後再執行攔截的時候需要使用這個參數。自定義攔截注解必須使用@InterceptMark标記,并且注解中必須包括include()、exclude()、handler()屬性資訊 。使用的步驟主要分為3步:
- 自定義攔截注解
- 繼承BasePathMatchInterceptor編寫攔截處理器
- 接口上使用自定義攔截注解;
例如我們需要在請求頭裡面動态加入accessKeyId、accessKeySecret簽名資訊才能正常發起http請求 ,這個時候可以自定義一個加簽攔截器注解@Sign來實作
請求重試
在接口或者方法上加上@Retry注解即可。@Retry支援重試次數maxRetries、重試時間間隔intervalMs以及重試規則retryRules配置
錯誤解碼器
在HTTP發生請求錯誤(包括發生異常或者響應資料不符合預期)的時候,錯誤解碼器可将HTTP相關資訊解碼到自定義異常中。你可以在@RetrofitClient注解的errorDecoder()指定目前接口的錯誤解碼器,自定義錯誤解碼器需要實作ErrorDecoder接口。
每天一個小知識,每天進步一點點!!![加油][加油][加油]