欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring Cloud Feign 自定義配置(重試、攔截與錯(cuò)誤碼處理) 代碼實(shí)踐

 更新時(shí)間:2020年08月26日 09:28:50   作者:上帝愛吃蘋果-  
這篇文章主要介紹了Spring Cloud Feign 自定義配置(重試、攔截與錯(cuò)誤碼處理) 實(shí)踐,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

基于 spring-boot-starter-parent 2.1.9.RELEASE, spring-cloud-openfeign 2.1.3.RELEASE

引子

Feign 是一個(gè)聲明式、模板化的HTTP客戶端,簡(jiǎn)化了系統(tǒng)發(fā)起Http請(qǐng)求。創(chuàng)建它時(shí),只需要?jiǎng)?chuàng)建一個(gè)接口,然后加上FeignClient注解,使用它時(shí),就像調(diào)用本地方法一樣,作為開發(fā)者的我們完全感知不到這是在調(diào)用遠(yuǎn)程的方法,也感知不到背后發(fā)起了HTTP請(qǐng)求:

/**
 * @author axin
 * @suammry xx 客戶端
 */
@FeignClient(value = "xxClient",url = "${xx.host:www.axin.com}")
public interface DemoClient {

  @PostMapping(value = "/xxx/url", headers = "Content-Type=application/json"})
  yourResponse requestHTTP(@RequestBody JSONObject param);

}

上述的代碼就是一個(gè)定義一個(gè)Feign HTTP 客戶端,在其他類中只需要 @Autowired DemoClient,就可以像調(diào)用本地方法一樣發(fā)起HTTP請(qǐng)求。

介紹就到這,接下來進(jìn)入主題,因?yàn)?FeignClient 將發(fā)起HTTP請(qǐng)求與解析返回報(bào)文都做了包裝,如果你的業(yè)務(wù)場(chǎng)景需要定制一些調(diào)用機(jī)制,比如:

  • 我想在發(fā)起請(qǐng)求響應(yīng)超時(shí)失敗時(shí)自動(dòng)重試 —— 自定義重試機(jī)制
  • 我想單獨(dú)對(duì)某些異常的HTTP狀態(tài)碼特殊處理 —— 自定義ErrorDecoder
  • 服務(wù)端接口需要驗(yàn)證簽名,所以我方在發(fā)起請(qǐng)求時(shí)要生成簽名然后傳過去 —— 定義 Fegin 攔截器

基于此,本文就以上述3個(gè)需求場(chǎng)景為例來介紹如何自定義 FeignClient 的配置

FeignClient的默認(rèn)配置類

Feign Client 默認(rèn)的配置類為 FeignClientsConfiguration, 這個(gè)類在 spring-cloud-netflix-core 的 jar 包下。

默認(rèn)注入了很多 Feign 相關(guān)的配置Bean,包括FeignRetryer、 FeignLoggerFactory 和 FormattingConversionService 等。另外,Decoder、Encoder和 Contract 這3個(gè)類在沒有Bean被注入的情況下,會(huì)自動(dòng)注入默認(rèn)配置的 Bean,即ResponseEntity Decoder、SpringEncoder 和 SpringMvcContract。

如果你不知道如何自己定義配置時(shí),不放點(diǎn)進(jìn)去看看人家默認(rèn)配置是如何實(shí)現(xiàn)的。這里就不曬源碼了。

FeignClient 注解參數(shù)

每個(gè)注解參數(shù)都做了注釋,詳情請(qǐng)見下方源碼:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface FeignClient {

	/**
	 * 指定FeignClient的名稱,如果項(xiàng)目使用了Ribbon,name屬性會(huì)作為微服務(wù)的名稱,用于服務(wù)發(fā)現(xiàn)
	 */
	@AliasFor("name")
	String value() default "";
	@Deprecated
	String serviceId() default "";
	@AliasFor("value")
	String name() default "";
	
	/**
	 * Sets the <code>@Qualifier</code> value for the feign client.
	 * 這個(gè)bean在應(yīng)用上下文中的名字為接口的全限定名,你也可以使用 @FeignClient 注解中的 qualifier 屬性給bean指定一個(gè)別名
	 */
	String qualifier() default "";

	/**
	 * url地址
	 */
	String url() default "";

	/**
	 * 當(dāng)發(fā)生404錯(cuò)誤,如果該字段為true,會(huì)調(diào)用decoder進(jìn)行解碼,否則拋出FeignException
	 */
	boolean decode404() default false;

	/**
	 * 指定FeignClient 的配置類,優(yōu)先級(jí)最高,默認(rèn)的配置類為 FeignClientsConfiguration類
	 */
	Class<?>[] configuration() default {};

	/**
	 * 配置熔斷器的處理類
	 */
	Class<?> fallback() default void.class;

	/**
	 * 工廠類,用于生產(chǎn)fallback類示例,通過這個(gè)屬性我們可以實(shí)現(xiàn)每個(gè)接口通用的容錯(cuò)邏輯,減少重復(fù)代碼
	 */
	Class<?> fallbackFactory() default void.class;

	/**
	 * 定義統(tǒng)一的路徑前綴
	 */
	String path() default "";

	/**
	 * Whether to mark the feign proxy as a primary bean. Defaults to true.
	 */
	boolean primary() default true;
}

自定義Feign配置類

在 Spring Cloud 中,你可以通過 @FeignClient 注解聲明額外的配置(比 FeignClientsConfiguration 級(jí)別高)去控制feign客戶端,以一開始的feign接口為例:

/**
 * @author axin
 * @suammry xx 客戶端
 */
@FeignClient(value = "xxClient",url = "${xx.host:www.axin.com}",configuration = MyConfiguration.class)
public interface DemoClient {

  @PostMapping(value = "/xxx/url", headers = "Content-Type=application/json"})
  yourResponse requestHTTP(@RequestBody JSONObject param);
}

在上面這個(gè)示例中,feign客戶端在MyConfiguration中的配置將會(huì)覆蓋FeignClientsConfiguration中的配置。

要注意的是: MyConfiguration不需要使用@Configuration注解。如果加上了,它將全局生效。

Retryer-重試機(jī)制的自定義

/**
 * @author axin
 * @summary fegin 客戶端的自定義配置
 */
public class MyConfiguration {

  /**
   * 自定義重試機(jī)制
   * @return
   */
  @Bean
  public Retryer feignRetryer() {
    //fegin提供的默認(rèn)實(shí)現(xiàn),最大請(qǐng)求次數(shù)為5,初始間隔時(shí)間為100ms,下次間隔時(shí)間1.5倍遞增,重試間最大間隔時(shí)間為1s,
    return new Retryer.Default();
  }
}

ErrorDecoder-錯(cuò)誤解碼器的自定義

當(dāng)feign調(diào)用返回HTTP報(bào)文時(shí),會(huì)觸發(fā)這個(gè)方法,方法內(nèi)可以獲得HTTP狀態(tài)碼,可以用來定制一些處理邏輯等等。

/**
 * @author axin
 * @summary fegin 客戶端的自定義配置
 */
@Slf4j
public class MyConfiguration {

  /**
   * 自定義重試機(jī)制
   * @return
   */
  @Bean
  public Retryer feignRetryer() {
    //最大請(qǐng)求次數(shù)為5,初始間隔時(shí)間為100ms,下次間隔時(shí)間1.5倍遞增,重試間最大間隔時(shí)間為1s,
    return new Retryer.Default();
  }

  @Bean
  public ErrorDecoder feignError() {
    return (key, response) -> {
      if (response.status() == 400) {
        log.error("請(qǐng)求xxx服務(wù)400參數(shù)錯(cuò)誤,返回:{}", response.body());
      }

      if (response.status() == 409) {
        log.error("請(qǐng)求xxx服務(wù)409異常,返回:{}", response.body());
      }

      if (response.status() == 404) {
        log.error("請(qǐng)求xxx服務(wù)404異常,返回:{}", response.body());
      }

      // 其他異常交給Default去解碼處理
      // 這里使用單例即可,Default不用每次都去new
      return new ErrorDecoder.Default().decode(key, response);
    };
  }

}

采用了lambda的寫法,response變量是Response類型,通過status()方法可以拿到返回的HTTP狀態(tài)碼,body()可以獲得到響應(yīng)報(bào)文。

Feign攔截器實(shí)踐

攔截器在請(qǐng)求發(fā)出之前執(zhí)行,在攔截器代碼里可以修改請(qǐng)求參數(shù),header等等,如果你有簽名生成的需求,可以放在攔截器中來實(shí)現(xiàn)

/**
 * @author axin
 * @summary fegin 客戶端的自定義配置
 */
@Slf4j
public class MyConfiguration {

  /**
   * 自定義重試機(jī)制
   * @return
   */
  @Bean
  public Retryer feignRetryer() {
    //最大請(qǐng)求次數(shù)為5,初始間隔時(shí)間為100ms,下次間隔時(shí)間1.5倍遞增,重試間最大間隔時(shí)間為1s,
    return new Retryer.Default();
  }

  @Bean
  public ErrorDecoder feignError() {
    return (key, response) -> {
      if (response.status() == 400) {
        log.error("請(qǐng)求xxx服務(wù)400參數(shù)錯(cuò)誤,返回:{}", response.body());
      }

      if (response.status() == 409) {
        log.error("請(qǐng)求xxx服務(wù)409異常,返回:{}", response.body());
      }

      if (response.status() == 404) {
        log.error("請(qǐng)求xxx服務(wù)404異常,返回:{}", response.body());
      }

      // 其他異常交給Default去解碼處理
      // 這里使用單例即可,Default不用每次都去new
      return new ErrorDecoder.Default().decode(key, response);
    };
  }

   /**
   * fegin 攔截器
   * @return
   */
  @Bean
  public RequestInterceptor cameraSign() {
    return template -> {

      // 如果是get請(qǐng)求
      if (template.method().equals(Request.HttpMethod.GET.name())) {
        //獲取到get請(qǐng)求的參數(shù)
        Map<String, Collection<String>> queries = template.queries();
      }

      //如果是Post請(qǐng)求
      if (template.method().equals(Request.HttpMethod.POST.name())) {
        //獲得請(qǐng)求body
        String body = template.requestBody().asString();
        JSONPObject request = JSON.parseObject(body, JSONPObject.class);
      }

      //Do what you want... 例如生成接口簽名

      String sign = "根據(jù)請(qǐng)求參數(shù)生成的簽名";
      //放入url?之后
      template.query("sign", sign);

      //放入請(qǐng)求body中
      String newBody = "原有body" + sign;
      template.body(Request.Body.encoded(newBody.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8));
    };
  }
}

可以看到代碼中給了如何獲取請(qǐng)求參數(shù)和修改請(qǐng)求參數(shù)的示例。

總結(jié)

小結(jié)一下,對(duì)于開頭提出的場(chǎng)景:

  1. 我想在發(fā)起請(qǐng)求響應(yīng)超時(shí)失敗時(shí)自動(dòng)重試 —— 自定義重試機(jī)制
  2. 我想單獨(dú)對(duì)某些異常的HTTP狀態(tài)碼特殊處理 —— 自定義ErrorDecoder
  3. 服務(wù)端接口需要驗(yàn)證簽名,所以我方在發(fā)起請(qǐng)求時(shí)要生成簽名然后傳過去 —— 定義 Fegin 攔截器

給出了自定義 feign 配置的方式實(shí)現(xiàn)的樣例代碼,希望對(duì)你有用,如果有更好的方式簡(jiǎn)化HTTP請(qǐng)求,歡迎留言分享~

參考鏈接

重新定義Spring Cloud實(shí)戰(zhàn)

Spring Cloud Netflix官方文檔

總結(jié)

到此這篇關(guān)于Spring Cloud Feign 自定義配置(重試、攔截與錯(cuò)誤碼處理) 實(shí)踐的文章就介紹到這了,更多相關(guān)Spring Cloud Feign 自定義配置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JavaWeb驗(yàn)證碼校驗(yàn)功能代碼實(shí)例

    JavaWeb驗(yàn)證碼校驗(yàn)功能代碼實(shí)例

    這篇文章主要介紹了JavaWeb驗(yàn)證碼校驗(yàn)功能代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-04-04
  • Java?String之contains方法的使用詳解

    Java?String之contains方法的使用詳解

    這篇文章主要介紹了Java?String之contains方法的使用詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • JDBC下Idea添加mysql-jar包的詳細(xì)過程

    JDBC下Idea添加mysql-jar包的詳細(xì)過程

    這篇文章主要介紹了JDBC下Idea添加mysql-jar包的詳細(xì)過程,添加jar包首先到官網(wǎng)下載jar包,然后idea導(dǎo)入jar包,在就是檢查,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-11-11
  • response.sendRedirect()實(shí)現(xiàn)重定向(頁(yè)面跳轉(zhuǎn))

    response.sendRedirect()實(shí)現(xiàn)重定向(頁(yè)面跳轉(zhuǎn))

    在Java web開發(fā)中,使用response.sendRedirect()可實(shí)現(xiàn)重定向功能。本文將介紹如何使用該方法進(jìn)行頁(yè)面跳轉(zhuǎn),以及該方法的使用場(chǎng)景和注意事項(xiàng),感興趣的可以了解一下
    2023-04-04
  • SpringBoot與spring security的結(jié)合的示例

    SpringBoot與spring security的結(jié)合的示例

    這篇文章主要介紹了SpringBoot與spring security的結(jié)合的示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-03-03
  • mybatis實(shí)現(xiàn)mapper配置并查詢數(shù)據(jù)的思路詳解

    mybatis實(shí)現(xiàn)mapper配置并查詢數(shù)據(jù)的思路詳解

    這篇文章主要介紹了mybatis實(shí)現(xiàn)mapper配置并查詢數(shù)據(jù),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • Java開發(fā)者就業(yè)需要掌握的9大專業(yè)技能

    Java開發(fā)者就業(yè)需要掌握的9大專業(yè)技能

    這篇文章主要為大家詳細(xì)介紹了java就業(yè)前需要掌握的專業(yè)技能,感興趣的小伙伴們可以參考一下
    2016-09-09
  • 如何劫持Java應(yīng)用的HTTP請(qǐng)求

    如何劫持Java應(yīng)用的HTTP請(qǐng)求

    這篇文章主要介紹了如何劫持Java應(yīng)用的HTTP請(qǐng)求,幫助大家針對(duì)部分特殊的流量,希望將它引導(dǎo)到特定服務(wù)上,感興趣的朋友可以了解下
    2020-10-10
  • 多線程計(jì)數(shù),怎么保持計(jì)數(shù)準(zhǔn)確的方法

    多線程計(jì)數(shù),怎么保持計(jì)數(shù)準(zhǔn)確的方法

    這篇文章主要介紹了多線程計(jì)數(shù)的方法,有需要的朋友可以參考一下
    2014-01-01
  • Scala方法與函數(shù)使用和定義詳解

    Scala方法與函數(shù)使用和定義詳解

    這個(gè)章節(jié)會(huì)很燒腦,需要認(rèn)真研讀,我會(huì)盡量寫的詳細(xì)一些。 方法和函數(shù),看似是兩個(gè)概念,其實(shí)他嚴(yán)格來說也是兩個(gè)概念,但我們大可以理解成是同一個(gè)概念,在使用時(shí)只有語(yǔ)法上的細(xì)微差別,是很類似的,都理解為function即可
    2022-12-12

最新評(píng)論