Spring MVC項目使用Feign聲明式服務調用

  • 2019 年 10 月 4 日
  • 筆記

文章目錄

Spring MVC項目使用Feign聲明式服務調用

什麼是聲明式服務調用?

拆分成 聲明式 服務調用

什麼聲明式?

可以從編程範式入手了解:

編程範式:

  • 命令式編程(Imperative Programming)
  • 聲明式編程(Declarative Programming)
  • 函數式編程(Funational Programming)
  • 面向對象編程(Object-oriented Programming)

聲明式編程範式:聲明式編程表明想要實現什麼目的,應該做什麼,但是不指定具體怎麼做。

注: 非官方解釋

聲明式服務調用: 聲明調用的URL地址,請求方式,和返回結果,但具體如何調用交給底層實現.

為什麼要使用聲明式服務調用?

  1. 對系統使用方,通過設計聲明式的接口,開發者無需關心底層實現,而更多的關註上層業務
  2. 對系統實現方,通過聲明式的接口,上層使用者接口相對穩定前提下,系統可以不斷的迭代優化
  3. 對整個系統而言,能夠更系統的收集更多信息,能夠依據策略進行系統行為優化,提升系統效率

Feign聲明式web客戶端

使用Feign,只需要聲明一個接口即可,不需要關心傳參、發送請求、獲取響應內容、關閉連接等細節,Feign全部幫我們做好了。

SpringCloud集成了Feign組件,使得SpringCloud服務間調用變得更簡單,方便

這裡並不是SpringCloud的項目,那如何引入Feign到普通的SpringMVC項目中呢?

SpringMVC集成Feign客戶端

1.引入maven依賴

<!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-core -->  <dependency>      <groupId>io.github.openfeign</groupId>      <artifactId>feign-core</artifactId>      <version>10.2.0</version>  </dependency>  <!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-gson -->  <dependency>      <groupId>io.github.openfeign</groupId>      <artifactId>feign-gson</artifactId>      <version>10.2.0</version>  </dependency>

2. 創建接口,聲明接口方法

這裡使用YesAPI作為第三方服務調用測試

這裡以全國大學接口為例:

可以根據大學名稱、學校類型、所在省份、所在城市等搜索大學

請求(查找全部師範大學):  http://api.yesapi.cn/?s=App.Common_University.Search&school_name=師範&app_key={你的app_key}&sign={動態簽名}    返回:  {      "ret": 200,      "data": {          "err_code": 0,          "err_msg": "",          "schools": [              {                  "school_name": "北京師範大學",                  "school_province": "北京",                  "school_level": "本科",                  "school_website": "http://www.bnu.edu.cn/",                  "school_city": "北京市"              }...          ]      },      "msg": "當前請求接口:App.Common_University.Search"  }

1.封裝返回實體

可以看到小白開放平台是有統一返回體的,我們可以封裝起來,也可以直接用Object或者Map來接收數據.我選擇數據封裝.

YesResponse.java

@Data  public class YesResponse<T> {      private Integer ret;      private String msg;      private T data;  }

YesUniversity.java

@Data  public class YesUniversity {      private String err_code;      private String err_msg;      private List<School> schools;  }

School.java

@Data  public class School {      private String school_name;      private String school_province;      private String school_level;      private String school_website;      private String school_city;  }

2.聲明參數

既然是聲明式服務調用,必須先聲明再調用,結果已經聲明了,接下來就是聲明參數了,我依然選擇數據封裝;

可以從上面的請求示例看到,需要3個參數.

YesVo.java

@Data  public class YesVo {      private String school_name;      private String app_key;      private String sign;  }

3.聲明接口

參數和結果都已經封裝好了,接下來就是聲明服務接口了

一般是根據對方的uri命名接口

Yes.java

public interface Yes {      @RequestLine("POST /?s=App.Common_University.Search")      YesResponse<YesUniversity> appCommonUniversitySearch(@QueryMap YesVo vo);  }

如上,一個服務接口已經聲明好了,因為這裡使用的是post請求,@QueryMap可以把對象轉為body體的參數,@RequestLine可以聲明其服務路徑

4.服務接口調用

通過service層的封裝,可以把一些業務邏輯寫在裏面

public class YesService {      public YesResponse<YesUniversity> appCommonUniversitySearch(){          Yes yes=Feign.builder().decoder(new GsonDecoder()).target(Yes.class,"http://api.yesapi.cn");          YesVo yesVo=new YesVo();          yesVo.setSchool_name("師範");          yesVo.setApp_key("你的app_key");          yesVo.setSign("你的sign");          return yes.appCommonUniversitySearch(yesVo);      }        public static void main(String[] args) {          YesService yesService = new YesService();          YesResponse<YesUniversity> yesUniversityYesResponse = yesService.appCommonUniversitySearch();          System.out.println(JSON.toJSONString(yesUniversityYesResponse));      }  }

那出現400,500這些異常怎麼辦?

Feign組件考慮到了,Feign封裝了一個Exception叫FeignException

結構如下圖:這樣我們可以通過這個FeignException的內置API達到我們對接服務的效果.

如果是同一個平台的服務,可以直接在對應的接口上增加接口方法:比如Yes接口

@RequestLine("GET ?service={service}&app_key={appKey}&sign={sign}")Result<JokeInfo<String>> res(@Param("service") String service,@Param("appKey") String appKey, @Param("sign") String sign);

如上的GET請求的寫法,也是可以支持的.

3.更多的用法

使用Feign還有更多的用法,可以參考其官方的用法,傳送門

vice") String service,@Param(「appKey」) String appKey, @Param(「sign」) String sign);

**如上的GET請求的寫法,也是可以支持的.**    ### 3.更多的用法    使用Feign還有更多的用法,可以參考其官方的用法,[傳送門](https://github.com/OpenFeign/feign)