一款優秀、開源的 http 框架

如果你因爲業務關係,要和許多不同第三方公司進行對接。這些服務商都提供基於 http 的 api。但是每家公司提供 api 具體細節差別很大。有的基於 RESTFUL 規範,有的基於傳統的 http 規範;有的需要在 header 裏放置簽名,有的需要 SSL 的雙向認證,有的只需要 SSL 的單向認證;有的以 JSON 方式進行序列化,有的以 XML 方式進行序列化。類似於這樣細節的差別太多了。

不同的公司 API 規範不一樣,這很正常。但是對於我來說,我如果想要代碼變得優雅。我就必須解決一個痛點:

不同服務商 API 那麼多的差異點,如何才能維護一套不涉及業務的公共 http 調用套件。最好通過配置或者簡單的參數就能區分開來。進行方便的調用?

我當然知道有很多優秀的大名鼎鼎的 http 開源框架可以實現任何形式的 http 調用,在多年的開發經驗中我都有使用過。比如 apache 的 httpClient 包,非常優秀的 Okhttp,jersey client。

這些 http 開源框架的接口使用相對來說,都不太一樣。不管選哪個,在我這個場景裏來說,我都不希望在調用每個第三方的 http api 時寫上一堆 http 調用代碼。

所以,在這個場景裏,我得對每種不同的 http api 進行封裝。這樣的代碼才能更加優雅,業務代碼和 http 調用邏輯耦合度更低。

可惜,我比較懶。一來覺得封裝起來比較費時間,二來覺對封裝這種底層 http 調用來說,應該有更好的選擇。不想自己再去造輪子。

於是,我發現了一款優秀的開源 http 框架,能屏蔽不同細節 http api 所帶來的所有差異。能通過簡單的配置像調用 rpc 框架一樣的去完成極爲複雜的 http 調用。

https://gitee.com/dromara/forest

上手

Forest 支持了 Springboot 的自動裝配,所以只需要引入一個依賴就行

<dependency>
  <groupId>com.dtflys.forest</groupId>
  <artifactId>spring-boot-starter-forest</artifactId>
  <version>1.3.0</version>
</dependency>
```java
定義自己的接口類

public interface MyClient {

@Request(url = "http://baidu.com")
String simpleRequest();

@Request(
        url = "http://ditu.amap.com/service/regeo",
        dataType = "json"
)
Map getLocation(@DataParam("longitude") String longitude, @DataParam("latitude") String latitude);

}

在啓動類裏配置代理接口類的掃描包
```jva
@SpringBootApplication
@ForestScan(basePackages = "com.example.demo.forest")
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}

這時候,你就可以從 spring 容器中注入你的代理接口,像調用本地方法一樣去調用 http 的 api 了

@Autowired
private MyClient myClient;

@Override
public void yourMethod throws Exception {
    Map result = myClient.getLocation("124.730329","31.463683");
    System.out.println(JSON.toJSONString(result,true));
}

日誌打印,Forest 打印了內部所用的 http 框架,和實際請求 url 和返回。當然日誌可以通過配置去控制開關。

特點

我覺得對於尤其是做對接第三方 api 的開發同學來說,這款開源框架能幫你提高很多效率。

Forest 底層封裝了 2 種不同的 http 框架:Apache httpClient 和 OKhttp。所以這個開源框架並沒有對底層實現進行重複造輪子,而是在易用性上面下足了功夫。

我用 Forest 最終完成了和多個服務商 api 對接的項目,這些風格迥異的 API,我僅用了 1 個小時時間就把他們轉化爲了本地方法。然後項目順利上線。

Forest 作爲一款更加高層的 http 框架,其實你並不需要寫很多代碼,大多數時候,你僅通過一些配置就能完成 http 的本地化調用。而這個框架所能覆蓋的面,卻非常之廣,滿足你絕大多數的 http 調用請求。

Forest 有以下特點:
兩個很棒的功能

這裏不對使用方式和配置方式一一描述,有興趣的可以去閱讀詳細文檔:

http://forest.dtflyx.com/

這裏只想分析這個框架 2 個我認爲比較好的功能

模板表達式在使用的時候特別方便,舉個栗子

@Request(
    url = "${0}/send?un=${1}&pw=${2}&ph=${3}&ct=${4}",
    type = "get",
    dataType = "json"
)
public Map send(
    String base,
    String userName,
    String password,
    String phone,
    String content
);

上述是用序號下標進行取值,也可以通過名字進行取值:

@Request(
    url = "${base}/send?un=${un}&pw=${pw}&ph=${3}&ct=${ct}",
    type = "get",
    dataType = "json"
)
public Map send(
    @DataVariable("base") String base,
    @DataVariable("un") String userName,
    @DataVariable("pw") String password,
    @DataVariable("ph") String phone,
    @DataVariable("ct") String content
);

甚至於可以這樣簡化寫:

@Request(
    url = "${base}/send",
    type = "get",
    dataType = "json"
)
public Map send(
    @DataVariable("base") String base,
    @DataParam("un") String userName,
    @DataParam("pw") String password,
    @DataParam("ph") String phone,
    @DataParam("ct") String content
);

以上三種寫法是等價的

當然你也可以把參數綁定到 header 和 body 裏去,你甚至於可以用一些表達式簡單的把對象序列化成 json 或者 xml:

@Request(
    url = "${base}/pay",
   contentType = "application/json",
    type = "post",
    dataType = "json",
    headers = {"Authorization: ${1}"},
    data = "${json($0)}"
)
public PayResponse pay(PayRequest request, String auth);

當然數據綁定這塊詳情請參閱文檔

以前用其他 http 框架處理 https 的時候,總覺得特別麻煩,尤其是雙向證書。每次碰到問題也只能去 baidu。然後根據別人的經驗來修改自己的代碼。

Forest 對於這方面也想的很周到,底層完美封裝了對 https 單雙向證書的支持。也是隻要通過簡單的配置就能迅速完成。舉個雙向證書栗子:

@Request(
    url = "${base}/pay",
   contentType = "application/json",
    type = "post",
    dataType = "json",
   keyStore = "pay-keystore",
   data = "${json($0)}"
)
public PayResponse pay(PayRequest request);

其中 pay-keystore 對應着 application.yml 裏的 ssl-key-stores

forest:
  ...
  ssl-key-stores:
    - id: pay-keystore
      file: test.keystore
      keystore-pass: 123456
      cert-pass: 123456
      protocols: SSLv3

這樣設置,就 ok 了,剩下的,就是本地代碼形式的調用了。

最後

Forest 有很多其他的功能設定,如果感興趣的同學還請仔細去閱讀文檔和示例。

但是我想說的是,相信看到這裏,很多人一定會說,這不就是 Feign 嗎?

我在開發 Spring Cloud 項目的時候,也用過一段時間 Feign,個人感覺 Forest 的確在配置和用法上和 Feign 的設計很像,但 Feign 的角色更多是作爲 Spring Cloud 生態裏的一個成員。充當 RPC 通信的角色,其承擔的不僅是 http 通訊,還要對註冊中心下發的調用地址進行負載均衡。

而 Forest 這個開源項目其定位則是一個高階的 http 工具,主打友好和易用性。從使用角度出發,個人感覺 Forest 配置性更加簡單直接。提供的很多功能也能解決很多人的痛點。

開源精神難能可貴,好的開源需要大家的添磚加瓦和支持。希望這篇文章能給大家在選擇 http 客戶端框架時帶來一個新的選擇:Forest

來源:cnblogs.com/bryan31/p/13359376.html

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/-8HZPPTHYRvhB2Hq4jb7Lw