一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務器之家 - 編程語言 - Java教程 - 一文教你如何使用原生的Feign

一文教你如何使用原生的Feign

2022-03-07 00:49子月生 Java教程

Feign使得 Java HTTP 客戶端編寫更方便,Feign 靈感來源于Retrofit、JAXRS-2.0和WebSocket,這篇文章主要給大家介紹了如何使用原生的Feign的相關資料,需要的朋友可以參考下

什么是Feign

Feign 是由 Netflix 團隊開發的一款基于 Java 實現的 HTTP client,借鑒了 Retrofit、 JAXRS-2.0、WebSocket 等類庫。通過 Feign,我們可以像調用方法一樣非常簡單地訪問 HTTP API。這篇博客將介紹如何使用原生的 Feign,注意,是原生的,不是經過 Spring 層層封裝的 Feign。

補充一下,在 maven 倉庫中搜索 feign,我們會看到兩種 Feign: OpenFeign Feign 和 Netflix Feign。它們有什么區別呢?簡單地說,OpenFeign Feign 的前身就是 Netflix Feign,因為 Netflix Feign 從 2016 年開始就不維護了,所以建議還是使用 OpenFeign Feign。

 

一文教你如何使用原生的Feign

 

為什么使用Feign

為什么要使用HTTP client

首先,因為 Feign 本身是一款 HTTP client,所以,這里先回答:為什么使用 HTTP client?

假設不用 HTTP client,我們訪問 HTTP API 的過程大致如下。是不是相當復雜呢?直接操作 socket 已經非常麻煩了,我們還必須在熟知 HTTP 協議的前提下自行完成報文的組裝和解析,代碼的復雜程度可想而知。

 

一文教你如何使用原生的Feign

那么,這個過程是不是可以更簡單一些呢?

我們可以發現,在上面的圖中,紅框的部分是相對通用的,是不是可以把這些邏輯封裝起來?基于這樣的思考,于是就有了 HTTP client(根據類庫的不同,封裝的層次會有差異)。

所以,為什么要使用 HTTP client 呢?簡單地說,就是為了讓我們更方便地訪問 HTTP API。

為什么要使用Feign

HTTP client 的類庫還有很多,例如 Retrofit、JDK 自帶的 HttpURLConnection、Apache HttpClient、OkHttp、Spring 的 RestTemplate,等等。我很少推薦說要使用哪種具體的類庫,如果真的要推薦 Feign 的話,主要是由于它優秀的擴展性(不是一般的優秀,后面的使用例子就可以看到)。

 

如何使用Feign

關于如何使用 Feign,官方給出了非常詳細的文檔,在我看過的第三方類庫中,算是比較少見的。

本文用到的例子也是參考了官方文檔。

項目環境說明

os:win 10

jdk:1.8.0_231

maven:3.6.3

IDE:Spring Tool Suite 4.6.1.RELEASE

引入依賴

這里引入 gson,是因為入門例子需要有一個 json 解碼器。

  <properties>
      <feign.version>11.2</feign.version>
  </properties>
  
  <dependencies>
      <dependency>
          <groupId>io.github.openfeign</groupId>
          <artifactId>feign-core</artifactId>
          <version>${feign.version}</version>
      </dependency>
      <dependency>
          <groupId>io.github.openfeign</groupId>
          <artifactId>feign-gson</artifactId>
          <version>${feign.version}</version>
      </dependency>
  </dependencies>

入門例子

入門例子中使用 Feign 來訪問 github 的接口獲取 Feign 這個倉庫的所有貢獻者。

通過下面的代碼可以發現,Feign 本質上是使用了動態代理來生成訪問 HTTP API 的代碼,定義 HTTP API 的過程有點像在定義 advice。

// 定義HTTP API
interface GitHub {
  
  @RequestLine("GET /repos/{owner}/{repo}/contributors")
  // @RequestLine(value = "GET /repos/{owner}/{repo}/contributors", decodeSlash = false)// 測試轉義"/"、"+"
  // @RequestLine("GET /repos/{owner:[a-zA-Z]*}/{repo}/contributors")// 測試正則校驗
  // @Headers("Accept: application/json") // 測試添加header
  List<Contributor> contributors(@Param("owner") String owner, @Param("repo") String repo);
}

public static class Contributor {
  String login;
  int contributions;
}

public class MyApp {

  public static void main(String... args) {
      // 獲取用來訪問HTTP API的代理類
      GitHub github = Feign.builder()
              .decoder(new GsonDecoder()) // 返回內容為json格式,所以需要用到json解碼器
              // .options(new Request.Options(10, TimeUnit.SECONDS, 60, TimeUnit.SECONDS, true)) // 配置超時參數等
              .target(GitHub.class, "https://api.github.com");

      // 像調用方法一樣訪問HTTP API
      github.contributors("OpenFeign", "feign").stream()
          .map(contributor -> contributor.login + " (" + contributor.contributions + ")")
          .forEach(System.out::println);
  }
}

個性化配置

除了簡單方便之外,Feign 還有一個很大的亮點,就是有相當優秀的擴展性,幾乎什么都可以自定義。下面是官方給的一張圖,基本涵蓋了 Feign 可以擴展的內容。每個擴展支持都有一個對應的適配包,例如,更換解碼器為 jackson 時,需要引入io.github.openfeign:feign-jackson的適配包。

一文教你如何使用原生的Feign

更換為Spring的注解

在入門例子中,我們使用 Feign 自帶的注解來定義 HTTP API。但是,對于習慣了 Spring 注解的許多人來說,無疑需要增加學習成本。我們自然會問,Feign 能不能支持 Spring 注解呢?答案是肯定的。Feign 不但能支持 Spring 注解,還可以支持 JAX-RS、SOAP 等等。

 

一文教你如何使用原生的Feign

下面就是使用 Sping 注解定義 HTTP API 的例子。注意,pom 文件中要引入 io.github.openfeign:feign-spring4 的依賴。

// 定義HTTP API
interface GitHub {
  
  @GetMapping("/repos/{owner}/{repo}/contributors")
  List<Contributor> contributors(@RequestParam("owner") String owner, @RequestParam("repo") String repo);
}


public class MyApp {

  public static void main(String... args) {
      // 獲取用來訪問HTTP API的代理類
      GitHub github = Feign.builder()
              .decoder(new GsonDecoder())
              .contract(new SpringContract())// 自定義contract
              .target(GitHub.class, "https://api.github.com");
  }
}

自定義解碼器和編碼器

在入門例子中,我們使用 gson 來解析 json。那么,如果我想把它換成 jackson 行不行?Feign 照樣提供了支持。

 

一文教你如何使用原生的Feign

注意,pom 文件中要引入 io.github.openfeign:feign-jackson 的依賴。

public class MyApp {

  public static void main(String... args) {
      // 獲取用來訪問HTTP API的代理類
      GitHub github = Feign.builder()
              .decoder(new JacksonDecoder()) // 自定義解碼器
              .encoder(new JacksonEncoder()) // 自定義編碼器
              .target(GitHub.class, "https://api.github.com");
  }
}

自定義內置的HTTP client

接下來的這個自定義就更厲害了。Feign 本身作為一款 HTTP client,竟然還可以支持其他 HTTP client。

 

一文教你如何使用原生的Feign

這里用 OkHttp 作例子。注意,pom 文件中要引入 io.github.openfeign:feign-okhttp 的依賴。

public class MyApp {

  public static void main(String... args) {
      // 獲取用來訪問HTTP API的代理類
      GitHub github = Feign.builder()
              .decoder(new GsonDecoder())
              .client(new OkHttpClient())// 自定義client
              .target(GitHub.class, "https://api.github.com");
  }
}

自定義攔截器

我們訪問外部接口時,有時需要帶上一些特定的 header,例如,應用標識、token,我們可以通過兩種方式實現:一是使用注解定義 HTTP API,二是使用攔截器(更常用)。下面的例子中,使用攔截器給請求添加 token 請求頭。

public class MyInterceptor implements RequestInterceptor {

  @Override
  public void apply(RequestTemplate template) {
      template.header("token", LoginUtils.getCurrentToken());
  }
}
public class MyApp {

  public static void main(String... args) {
      // 獲取用來訪問HTTP API的代理類
      GitHub github = Feign.builder()
              .decoder(new GsonDecoder())
              .requestInterceptor(new MyInterceptor())
              .target(GitHub.class, "https://api.github.com");
  }
}

自定義重試器

默認情況下,Feign 訪問 HTTP API 時,如果拋出IOException,它會認為是短暫的網絡異常而發起重試,這時,Feign 會使用默認的重試器feign.Retryer.Default(最多重試 5 次),如果不想啟用重試,則可以選擇另一個重試器feign.Retryer.NEVER_RETRY。當然,我們也可以自定義。

奇怪的是,Feign 通過重試器的 continueOrPropagate(RetryableException e)方法是否拋出RetryableException來判斷是否執行重試,為什么不使用 true 或 false 來判斷呢?

注意,重試器是用來判斷是否執行重試,自身不包含重試的邏輯。

public class MyRetryer implements Retryer {
  
  int attempt = 0;

  @Override
  public void continueOrPropagate(RetryableException e) {
      // 如果把RetryableException拋出,則不會繼續重試
      // 否則繼續重試
      if(attempt++ >= 3) {// 重試三次
          throw e;
      }
  }

  @Override
  public Retryer clone() {
      return this;
  }
}
public class MyApp {

  public static void main(String... args) {
      // 獲取用來訪問HTTP API的代理類
      GitHub github = Feign.builder()
              .decoder(new GsonDecoder())
              .retryer(new MyRetryer())
              //.retryer(Retryer.NEVER_RETRY) // 不重試
              .exceptionPropagationPolicy(ExceptionPropagationPolicy.UNWRAP)
              .target(GitHub.class, "https://api.github.com");
  }
}

 

結語

以上,基本講完 Feign 的使用方法,其實 Feign 還有其他可以擴展的東西,例如,斷路器、監控等等。感興趣的話,可以自行分析。

到此這篇關于如何使用原生的Feign的文章就介紹到這了,更多相關使用原生的Feign內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!

參考資料

原文鏈接:https://www.cnblogs.com/ZhangZiSheng001/p/14989165.html

延伸 · 閱讀

精彩推薦
  • Java教程Kotlin修飾符lateinit(延遲初始化)案例詳解

    Kotlin修飾符lateinit(延遲初始化)案例詳解

    這篇文章主要介紹了Kotlin修飾符lateinit(延遲初始化)案例詳解,本篇文章通過簡要的案例,講解了該項技術的了解與使用,以下就是詳細內容,需要的朋友可以參...

    ldxlz2249422021-12-15
  • Java教程SpringBoot+Spring Security無法實現跨域的解決方案

    SpringBoot+Spring Security無法實現跨域的解決方案

    這篇文章主要介紹了SpringBoot+Spring Security無法實現跨域的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜...

    dying 擱淺7032021-10-14
  • Java教程Java實現實時監控目錄下文件變化的方法

    Java實現實時監控目錄下文件變化的方法

    今天小編就為大家分享一篇關于Java實現實時監控目錄下文件變化的方法,小編覺得內容挺不錯的,現在分享給大家,具有很好的參考價值,需要的朋友一起...

    夢幻逝水3402019-06-21
  • Java教程淺談導入JavaWeb 項目出現的問題

    淺談導入JavaWeb 項目出現的問題

    這篇文章主要介紹了導入JavaWeb 項目出現的問題,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面...

    我心如鐵7732021-07-21
  • Java教程SpringSecurity構建基于JWT的登錄認證實現

    SpringSecurity構建基于JWT的登錄認證實現

    這篇文章主要介紹了SpringSecurity構建基于JWT的登錄認證實現,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的...

    locotor在掘金5742021-08-05
  • Java教程tomcat301與java301解析

    tomcat301與java301解析

    這篇文章主要介紹了tomcat301與java301,有需要的朋友可以參考一下 ...

    java技術網4452019-10-27
  • Java教程Java Map中那些巧妙的設計

    Java Map中那些巧妙的設計

    最近拜讀了一些Java Map的相關源碼,不得不驚嘆于JDK開發者們的鬼斧神工。他山之石可以攻玉,這些巧妙的設計思想非常有借鑒價值,可謂是最佳實踐。...

    阿里技術10122021-03-26
  • Java教程2020最新eclipse安裝過程及細節

    2020最新eclipse安裝過程及細節

    這篇文章主要介紹了2020最新eclipse安裝過程及細節,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的...

    力學猿11352020-08-12
主站蜘蛛池模板: 91精品国产美女福到在线不卡 | 亚洲欧美成人综合久久久 | 我半夜摸妺妺的奶C了她软件 | 国产日韩精品一区二区在线观看 | 加勒比一本大道香蕉在线视频 | 免费操比视频 | 日本一区二区三区四区无限 | 欧美四虎影院 | 女人肮脏的交易中文字幕未删减版 | 国产精品香蕉 | 亚洲国产欧美在线看片 | japonensis中国东北老人 | 亚洲日韩精品欧美一区二区一 | 欧美激烈精交gif动态图18p | 99精品国产美女福到在线不卡 | 四虎永久视频 | 免费一看一级毛片人 | 日本午夜大片免费观看视频 | 无限在线观看视频大全免费高清 | 91短视频在线免费观看 | 国产精品久久久久不卡绿巨人 | 91影视永久福利免费观看 | 国产欧美精品一区二区三区–老狼 | 国产精品久久久久久吹潮 | 成人精品区| 成人免费草草视频 | 操比软件| 男人视频网站 | 亚洲国产香蕉视频欧美 | 91久久国产视频 | 成全动漫视频在线观看 | 91国内精品久久久久影院优播 | 精品国产乱码久久久久久人妻 | 午夜福利08550| 2018高清国产一道国产 | 毛片小视频 | 日本免费不卡在线一区二区三区 | 国产成人精品一区二区不卡 | 4455四色永久免费 | 公交车强校花系列小说 | 免费视频|