背景
最近開發(fā)了一個統(tǒng)一調度類的項目檐什,需要依賴多個第三方服務牵祟,這些服務都提供了HTTP
接口供我調用深夯。
服務多、接口多诺苹,如何進行第三方服務管理和調用就成了問題咕晋。
常用的服務間調用往往采用zk
、Eureka
等注冊中心進行服務管理(SpringBoot
常使用SpringCloud
)收奔。OpenFeign
也是SpringCloud
的解決方案之一掌呜。我們單獨使用OpenFeign
, 無需對原有第三方服務進行改動坪哄,本服務開發(fā)時的引入也很輕量质蕉。
下面給出我的用法。
應用
maven依賴
引入maven依賴:
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>10.2.3</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-gson</artifactId>
<version>10.2.3</version>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form</artifactId>
<version>3.8.0</version>
</dependency>
<dependency>
<groupId>io.github.openfeign.form</groupId>
<artifactId>feign-form-spring</artifactId>
<version>3.8.0</version>
</dependency>
其中翩肌,form相關引入是為了解決ContentType
為application/x-www-form-urlencoded
和multipart/form-data
的編碼問題模暗。
配置和服務聲明
第三方服務的地址通過配置來注入。
服務地址配置
ThirdpartServiceConfig.java
@Data
@Component
@ConfigurationProperties(prefix = "thirdpart-service")
public class ThirdpartServiceConfig {
private String serviceA;
private String serviceB;
private String serviceC;
}
服務配置(超時時間配置等也可以寫在這里)
application.yaml
thirdpart-service:
serviceA: http://****:***/
serviceB: http://****:***/
serviceC: http://****:***/
第三方服務配置
因為聲明方法一致念祭,所以省略了多個第三方聲明兑宇。
ThirdPartClientConfig.java
@Configuration
public class ThirdParttClientConfig {
@Resource
private ThirdpartServiceConfig thirdpartServiceConfig;
@Bean
public ServiceAClient serviceAClient() {
return Feign.builder()
.encoder(new FormEncoder(new GsonEncoder()))
.decoder(new GsonDecoder())
.target(ServiceAClient.class, thirdpartServiceConfig.getServiceA());
}
}
接口聲明和使用
完成了服務的聲明和服務的配置之后,就可以進行服務接口的聲明了粱坤。具體聲明方法可以參看OpenFeign
文檔:# 翻譯: Spring Cloud Feign使用文檔
下面給出使用示例:
-
GET
請求(feign
可直接將返回的結果反序列化為本服務中定義的POJO
)
@RequestLine("GET testGet?a={a}&b=隶糕")
ServiceResp testGet(@Param("a") String a,@Param("b")String b);
-
GET
下載
使用feign.Response
接收請求結果
@RequestLine("GET export?exportId={exportId}")
Response exportFromServiceA(@Param("exportId")String exportId);
@Resource
private ServiceAClient serviceAClient ;
// 導出方法
public void export(exportId) {
Response serviceResponse = serviceserviceAClient.exportFromServiceA(exportId);
Response.Body body = serviceResponse.body();
try(InputStream inputStream = body.asInputStream();
// 處理獲取到的inputStream
} catch (IOException e) {
log.error("導出發(fā)生異常",e);
}
-
POST
application/json"
@RequestLine("POST /save")
@Headers("Cofntent-Type: application/json")
ServiceResp saveEntity(EntityPOJO entityPOJO);
- POST form
@RequestLine("POST uqa/repo/qa/batch")
@Headers("Content-Type:multipart/form-data")
ServiceResp uploadFile(@Param("id")String id, @Param("batch_file") File file);
- 注意:除了file類型,其他參數(shù)會被序列化為String站玄,所以若第三方接口參數(shù)的值為POJO(或Map)枚驻,可能會出錯。
- 對于POJO參數(shù)株旷,若第三方參數(shù)名含有
Java
中不合法的屬性字符(如 ”-“再登,”#“,”.“等)灾常,可使用注解進行序列化時的轉化霎冯。由于聲明Feign Client
時使用的encoder是Gson
铃拇,所以使用如下注解:
@SerializedName(value="aaa-bbb")
private String aaaBbb;
如果使用的是其他序列化工具钞瀑,改為對應的注解即可。
小結
使用聲明式的第三方和接口寫法慷荔,基本覆蓋了請求第三方接口的需求雕什,也易于拓展和管理。
我計劃在后續(xù)添加統(tǒng)一的鑒權、日志打印和異常捕獲處理功能贷岸,使依賴組件引入的風險更為可控壹士。OpenFeign
幫我們實現(xiàn)了服務聲明、接口聲明偿警、HTTP請求發(fā)送和結果處理等邏輯躏救,在項目需要調用多個第三方服務時可以使用。