自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

原來(lái)OpenFeign功能這么強(qiáng)大,你知道嗎?

開(kāi)發(fā) 前端
本文介紹了OpenFeign的基本使用方法,包括如何引入依賴、如何定義接口、如何構(gòu)建客戶端、如何自定義攔截器、重試器等。

OpenFeign是Spring微服務(wù)全家桶中的重要組件。前身是Netflix Feign,在2013年首次發(fā)布。2016年,Netflix發(fā)布了Feign的最后一個(gè)版本(8.18.0),并將其捐贈(zèng)給開(kāi)源社區(qū),隨后Feign更名為OpenFeign,于同年發(fā)布了OpenFeign的首個(gè)版本(9.0.0)。在2017年,Spring Cloud團(tuán)隊(duì)將對(duì)Feign的依賴升級(jí)為OpenFeign。

圖片圖片

OpenFeign和Netflix Feign

為了避免歧義,文中提到的Feign或OpenFeign,都是指 OpenFeign。

OpenFeign是Netflix團(tuán)隊(duì)開(kāi)發(fā)的一個(gè)聲明式、模板化的 Web 服務(wù)客戶端,目標(biāo)是開(kāi)發(fā)一種簡(jiǎn)單、優(yōu)雅的 HTTP 服務(wù)客戶端。在設(shè)計(jì)時(shí),借鑒了各種優(yōu)秀類庫(kù),比如Retrofit、 JAXRS-2.0、WebSocket等。

通過(guò)OpenFeign,我們可以像調(diào)用方法一樣實(shí)現(xiàn)HTTP API訪問(wèn)。

本文將介紹如何使用原生的 OpenFeign,原生的使用方式,不是集成在Spring Cloud中的使用方式。

來(lái),一起來(lái)。

先來(lái)個(gè)簡(jiǎn)單的例子

引入依賴

OpenFeign很貼心的提供了BOM,我們可以直接使用控制組件版本。

<project>
    ……
    <properties>
        <openfeign.version>13.4</openfeign.version>
    </properties>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.github.openfeign</groupId>
                <artifactId>feign-bom</artifactId>
                <version>${openfeign.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
</project>

我這里使用的是13.4版本(學(xué)習(xí)的時(shí)候就得學(xué)新的,新的bug少)。

然后引入core模塊:

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-core</artifactId>
</dependency>

有了前面的BOM,后面的模塊就不用指定版本了。

定義接口

private interface Client {
    @RequestLine("GET /anything/{anything}")
    @Headers({"Content-Type: application/json"})
    String anything(@Param("anything") String anything);
}

為了調(diào)用方便,我們借助https://httpbin.org提供的HTTP API接口anything用來(lái)驗(yàn)證,這個(gè)接口會(huì)返回傳入的參數(shù)。這樣也方便我們檢查調(diào)用是否正常。

創(chuàng)建客戶端

final Client client = Feign.builder()
        .logLevel(Level.FULL)
        .target(Client.class, "https://httpbin.org");
final String anything = client.anything("testCore");
Assertions.assertNotNull(anything);
Assertions.assertTrue(anything.contains("testCore"));
System.out.println(anything);

是不是非常簡(jiǎn)單,通過(guò)建造器模式簡(jiǎn)單配置下參數(shù),定義接口的域名,然后就像調(diào)用本地方法一樣調(diào)用接口,然后就拿到返回值了。

OpenFeign提供了很多的擴(kuò)展口,比如日志、解析器、攔截器、編碼器、錯(cuò)誤處理器等,可以通過(guò)builder方法進(jìn)行配置。

自定義編解碼器

OpenFeign提供了12種編解碼器,默認(rèn)使用的是字符串編解碼器,如果需要自定義編解碼器,可以通過(guò)builder方法進(jìn)行配置。

比如,我們想要使用Jackson實(shí)現(xiàn):

我們先引入feign-jackson模塊:

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-jackson</artifactId>
</dependency>

然后在建造器參數(shù)指定JacksonDecoder和JacksonEncoder:

final Client client = Feign.builder()
        .logLevel(Level.FULL)
        .decoder(new JacksonDecoder())
        .encoder(new JacksonEncoder())
        .target(Client.class, "https://httpbin.org");
final Map<String, Object> requestBody = Map.of("k1", "value1", "k2", "value2");
final Map<String, Object> anythingResult = client.anythingJson("testJson", requestBody);

如果想要換成Gson,引入feign-gson模塊,在建造器參數(shù)替換為GsonDecoder和GsonEncoder就行。

還有JAXB、Moshi、Fashjson、SAX等一種編解碼器可以使用。

自定義客戶端

OpenFeign默認(rèn)的客戶端是Java提供的HttpURLConnection,如果需要自定義客戶端,可以通過(guò)builder方法進(jìn)行配置。

比如,我們想要使用OkHttp,可以先引入feign-okhttp模塊:

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-okhttp</artifactId>
</dependency>

然后通過(guò)client方法替換:

final Client client = Feign.builder()
        .logLevel(Level.FULL)
        .decoder(new JacksonDecoder())
        .encoder(new JacksonEncoder())
        .client(new OkHttpClient())
        .target(Client.class, "https://httpbin.org");
final Map<String, Object> anythingResult = client.anythingJsonBodyTemplate("testJson", "value1", "value2");

此時(shí)使用的就是OkHttpClient了。

OpenFeign還支持Apache HTTP、Apache HC5、Google HTTP、Java11 HTTP2、Ribbon。

自定義攔截器

攔截器可以對(duì)請(qǐng)求和響應(yīng)進(jìn)行攔截處理,比如打印日志、添加請(qǐng)求頭、添加簽名等,可以使用requestInterceptor自定義攔截器。

首先,定義我們自己的攔截器,比如我們?cè)谡?qǐng)求頭中添加一個(gè)自定義的header:

public class MyRequestInterceptor implements RequestInterceptor {
    @Override
    public void apply(RequestTemplate template) {
        template.header("my-header", "my-value");
    }
}

然后指定攔截器:

final Client client = Feign.builder()
        .logLevel(Level.FULL)
        .decoder(new JacksonDecoder())
        .encoder(new JacksonEncoder())
        .requestInterceptor(new MyRequestInterceptor())
        .target(Client.class, "https://httpbin.org");
final Map<String, Object> anythingResult = client.anythingJsonBodyTemplate("testJson", "value1", "value2");
System.out.println(anythingResult);

Assertions.assertNotNull(anythingResult);
Assertions.assertTrue(anythingResult.get("url") instanceof String);
Assertions.assertTrue(((String) anythingResult.get("url")).endsWith("testJson"));
Assertions.assertTrue(anythingResult.containsKey("json"));
Assertions.assertTrue(anythingResult.get("json") instanceof Map<?, ?>);

Assertions.assertTrue(anythingResult.containsKey("headers"));
boolean hasMyHeader = false;
if (anythingResult.get("headers") instanceof Map headers) {
    for (Object key : headers.keySet()) {
        if (key.toString().equalsIgnoreCase("my-header")) {
            hasMyHeader = true;
            final Object value = headers.get(key);
            Assertions.assertTrue(value instanceof String);
            Assertions.assertEquals("my-value", value);
        }
    }
}
Assertions.assertTrue(hasMyHeader);

訪問(wèn)anything接口時(shí)會(huì)把請(qǐng)求頭的信息返回回來(lái),說(shuō)明攔截器執(zhí)行成功了。

自定義重試器

OpenFeign默認(rèn)的重試器是feign.Retryer.Default,共重試5次,每次間隔步長(zhǎng)為1.5的(重試次數(shù)-1)次冪,間隔最大1秒。

如果想要自定義重試邏輯,我們可以自己實(shí)現(xiàn)。

public class MyRetryer implements Retryer {
    int attempt = 0;

    @Override
    public void continueOrPropagate(RetryableException e) {
        if (attempt++ >= 3) {
            throw e;
        }
        System.out.println("重試第:" + attempt + "次");
        try {
            TimeUnit.MILLISECONDS.sleep(100);
        } catch (InterruptedException ex) {
             Thread.currentThread().interrupt();
            throw new RuntimeException(ex);
        }
    }

    @Override
    public Retryer clone() {
        return new MyRetryer();
    }
}

然后通過(guò)retryer方法指定。

final Client client = Feign.builder()
        .logLevel(Level.FULL)
        .decoder(new JacksonDecoder())
        .encoder(new JacksonEncoder())
        .retryer(new MyRetryer())
        // 默認(rèn)是 feign.Retryer.Default
        // 可以指定不重試 feign.Retryer.NEVER_RETRY
        .target(Client.class, "https://httpbin.abc");
Assertions.assertThrowsExactly(RetryableException.class, () -> client.codes("500"));

需要強(qiáng)調(diào)一下,只有訪問(wèn)HTTP時(shí)出現(xiàn)了IO異常才會(huì)重試,如果接口正常返回了,只不過(guò)不是200之類的正常響應(yīng),不會(huì)進(jìn)重試邏輯。示例中把域名寫錯(cuò)了,屬于IO異常,會(huì)重試3次。

如果不想重試,可以指定為feign.Retryer.NEVER_RETRY。

使用Spring的注解

OpenFeign接口定義使用的是URL模板,具體協(xié)議可以參https://www.rfc-editor.org/rfc/rfc6570.html。

大部分人對(duì)這個(gè)協(xié)議有些陌生,但是對(duì)Spring的注解比較屬性,所以O(shè)penFeign也貼心的提供了Spring契約適配。

首先,引入spring模塊依賴:

<dependency>
    <groupId>io.github.openfeign</groupId>
    <artifactId>feign-spring</artifactId>
</dependency>

這種方式引入的是Spring 6.x,如果想要使用Spring 4.x,可以引入feign-spring4模塊。

然后使用Spring MVC注解定義接口:

@PostMapping(value = "/anything/{anything}",
        produces = "application/json", consumes = "application/json")
Map<String, Object> anythingJsonSpring(@PathVariable("anything") String anything,
        @RequestParam("p1") String p1,
        @RequestParam("p2") String p2,
        @RequestBody Map<String, Object> requestBody);

構(gòu)建客戶端的時(shí)候,需要使用contract指定是Spring的契約:

final SpringClient client = Feign.builder()
        .logLevel(Level.FULL)
        .decoder(new JacksonDecoder())
        .encoder(new JacksonEncoder())
        .contract(new SpringContract())
        .target(SpringClient.class, "https://httpbin.org");
final Map<String, Object> requestBody = Map.of("k1", "value1", "k2", "value2");
final Map<String, Object> anythingResult = client.anythingJsonSpring("testJson",
        "param1", "param2", requestBody);

這樣就可以正常運(yùn)行了。

文末總結(jié)

本文介紹了OpenFeign的基本使用方法,包括如何引入依賴、如何定義接口、如何構(gòu)建客戶端、如何自定義攔截器、重試器等。

OpenFeign的入門篇結(jié)束,后續(xù)我們將介紹OpenFeign的更多功能,比如錯(cuò)誤處理器、熔斷器、監(jiān)控等。

圖片圖片

責(zé)任編輯:武曉燕 來(lái)源: 看山的小屋
相關(guān)推薦

2022-06-06 08:31:05

Base64編碼Base58

2019-12-30 09:51:35

Word設(shè)計(jì)模式軟件

2023-11-02 10:22:29

gRPC后端通信

2023-08-30 07:39:16

PawSQL數(shù)據(jù)庫(kù)

2020-12-24 18:44:34

RSA加密算法

2024-03-26 10:10:45

JavaScript操作符操作表達(dá)式

2022-09-07 09:01:14

JS操作符運(yùn)算符

2021-01-04 14:16:01

小程序地圖騰訊

2024-05-28 09:12:10

2024-04-07 00:00:00

ESlint命令變量

2018-04-24 15:40:39

無(wú)線路由器無(wú)線網(wǎng)絡(luò)上網(wǎng)

2023-12-12 08:41:01

2023-12-20 08:23:53

NIO組件非阻塞

2024-04-30 09:02:48

2023-04-26 10:21:04

2021-10-14 06:52:47

算法校驗(yàn)碼結(jié)構(gòu)

2022-11-04 14:16:05

2024-09-18 07:00:00

消息隊(duì)列中間件消息隊(duì)列

2025-02-18 08:11:17

2023-03-21 07:39:51

CentOS掛載硬盤
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)