關鍵操作
實現ErrorDecoder接口
問題和背景
最近項目中在大量使用Feign和OkHttp作為http客戶端使用,開發效率得到顯著的提升。但也面臨一些問題,比如每個下游系統的異常返回方式不同,需要編寫大量的錯誤處理代碼來適應不同的服務,而且錯誤處理代碼混在業務代碼中,違反單一職責原則和最少知識原則。面臨着維護難度上升的風險。需要一個方案來規避這些后期維護成本上升的風險。
目的
防止項目腐化,避免錯誤處理代碼與業務代碼強耦合。導致后期的維護成本的上升和陷入邏輯迷宮的風險。保證靈活性和高可維護性
手段
拆分錯誤處理代碼和業務邏輯代碼。由於使用的是 Feign和OkHttp作為客戶端,而企業場景下的開發通常有統一Trac請求的需求。首先想到的是客戶端的請求和響應的攔截器實現。
實施
查詢Feign的資料后發現Feign有 ErrorDecoder 接口。資料點這里
那我們只要實現Feign的 ErrorDecoder 的接口就可以實現 http請求層面的錯誤處理。
官方示例
public class StashErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
if (response.status() >= 400 && response.status() <= 499) {
return new StashClientException(
response.status(),
response.reason()
);
}
if (response.status() >= 500 && response.status() <= 599) {
return new StashServerException(
response.status(),
response.reason()
);
}
return errorStatus(methodKey, response);
}
}
解讀
StashErrorDecoder
類實現了ErrorDecoder
接口。在Feign客戶端發生http請求層面的錯誤時會調用decode
方法。在decode
方法中實現自定義的錯誤處理。
使用
接下來就需要注冊這個錯誤攔截器了,如果是直接手動構建FeignClient的使用方法。那需要在構建客戶端時指定errorDecoder
return Feign.builder()
.errorDecoder(new StashErrorDecoder())
.target(StashApi.class, url);
如果是使用了spring-cloud-open-feign的使用方式,包含了啟動的自動配置,所以只需要將錯誤處理類注冊為配置類,即添加@Configuration注解即可。
@Configuration
public class StashErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
// 實現代碼
}
}