Java | 使用OpenFeign管理多個第三方服務調用


背景

最近開發了一個統一調度類的項目,需要依賴多個第三方服務,這些服務都提供了HTTP接口供我調用。

組件架構

服務多、接口多,如何進行第三方服務管理和調用就成了問題。

常用的服務間調用往往采用zkEureka等注冊中心進行服務管理(SpringBoot常使用SpringCloud)。OpenFeign也是SpringCloud的解決方案之一。我們單獨使用OpenFeign, 無需對原有第三方服務進行改動,本服務開發時的引入也很輕量。

下面給出我的用法。

應用

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相關引入是為了解決ContentTypeapplication/x-www-form-urlencodedmultipart/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使用文檔
](https://segmentfault.com/a/1190000018313243?utm_source=tag-newest)
下面給出使用示例:

  • GET請求(feign可直接將返回的結果反序列化為本服務中定義的POJO
@RequestLine("GET testGet?a={a}&b={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("導出發生異常",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類型,其他參數會被序列化為String,所以若第三方接口參數的值為POJO(或Map),可能會出錯。
  • 對於POJO參數,若第三方參數名含有Java中不合法的屬性字符(如 ”-“,”#“,”.“等),可使用注解進行序列化時的轉化。由於聲明Feign Client時使用的encoder是Gson,所以使用如下注解:
 @SerializedName(value="aaa-bbb")
 private String aaaBbb;

如果使用的是其他序列化工具,改為對應的注解即可。

小結

使用聲明式的第三方和接口寫法,基本覆蓋了請求第三方接口的需求,也易於拓展和管理。
我計划在后續添加統一的鑒權、日志打印和異常捕獲處理功能,使依賴組件引入的風險更為可控。OpenFeign幫我們實現了服務聲明、接口聲明、HTTP請求發送和結果處理等邏輯,在項目需要調用多個第三方服務時可以使用。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM