一款直擊痛點的優(yōu)秀 HTTP 框架,讓我超高效完成了第三方接口的對接
轉自:www.cnblogs.com/bryan31/p/13359376.html
因為業(yè)務關系,要和許多不同第三方公司進行對接。這些服務商都提供基于 http 的 api。但是每家公司提供 api 具體細節(jié)差別很大。有的基于 RESTFUL 規(guī)范,有的基于傳統(tǒng)的 http 規(guī)范;有的需要再 header 里放置簽名,有的需要 SSL 的雙向認證,有的只需要 SSL 的單向認證;有的以 JSON 方式進行序列化,有的以 XML 方式進行序列化。類似于這樣細節(jié)的差別太多了。
不同的公司 API 規(guī)范不一樣,這很正常。但是對于我來說,我如果想要代碼變得優(yōu)雅。我就必須解決一個痛點:
不同服務商 API 那么多的差異點,如何才能維護一套不涉及業(yè)務的公共 http 調用套件。最好通過配置或者簡單的參數(shù)就能區(qū)分開來。進行方便的調用?
我當然知道有很多優(yōu)秀的大名鼎鼎的 http 開源框架可以實現(xiàn)任何形式的 http 調用,在多年的開發(fā)經(jīng)驗中我都有使用過。比如 apache 的 httpClient 包,非常優(yōu)秀的 Okhttp,jersey client。
這些 http 開源框架的接口使用相對來說,都不太一樣。不管選哪個,在我這個場景里來說,我都不希望在調用每個第三方的 http api 時寫上一堆 http 調用代碼。
所以,在這個場景里,我得對每種不同的 http api 進行封裝。這樣的代碼才能更加優(yōu)雅,業(yè)務代碼和 http 調用邏輯耦合度更低。
可惜,我比較懶。一來覺得封裝起來比較費時間,二來覺對封裝這種底層 http 調用來說,應該有更好的選擇。不想自己再去造輪子。
于是,我發(fā)現(xiàn)了一款優(yōu)秀的開源 http 框架,能屏蔽不同細節(jié) http api 所帶來的所有差異。能通過簡單的配置像調用 rpc 框架一樣的去完成極為復雜的 http 調用。
Forest
https://gitee.com/dt_flys/forest

2. 上手
Forest 支持了 Springboot 的自動裝配,所以只需要引入一個依賴就行
??com.dtflys.forest
??spring-boot-starter-forest
??1.3.0
定義自己的接口類
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);??
}
在啟動類里配置代理接口類的掃描包
@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));
}
日志打印,F(xiàn)orest 打印了內(nèi)部所用的 http 框架,和實際請求 url 和返回。當然日志可以通過配置去控制開關。

3. 特點
我覺得對于尤其是做對接第三方 api 的開發(fā)同學來說,這款開源框架能幫你提高很多效率。
搜索公縱號:MarkerHub,關注回復[?vue?]獲取前后端入門教程!
Forest 底層封裝了 2 種不同的 http 框架:Apache httpClient 和 OKhttp。所以這個開源框架并沒有對底層實現(xiàn)進行重復造輪子,而是在易用性上面下足了功夫。
我用 Forest 最終完成了和多個服務商 api 對接的項目,這些風格迥異的 API,我僅用了 1 個小時時間就把他們轉化為了本地方法。然后項目順利上線。
Forest 作為一款更加高層的 http 框架,其實你并不需要寫很多代碼,大多數(shù)時候,你僅通過一些配置就能完成 http 的本地化調用。而這個框架所能覆蓋的面,卻非常之廣,滿足你絕大多數(shù)的 http 調用請求。
Forest 有以下特點:
以 Httpclient 和 OkHttp 為后端框架 通過調用本地方法的方式去發(fā)送 Http 請求, 實現(xiàn)了業(yè)務邏輯與 Http 協(xié)議之間的解耦 相比 Feign 更輕量,不依賴 Spring Cloud 和任何注冊中心 支持所有請求方法:GET, HEAD, OPTIONS, TRACE, POST, DELETE, PUT, PATCH 支持靈活的模板表達式 支持過濾器來過濾傳入的數(shù)據(jù) 基于注解、配置化的方式定義 Http 請求 支持 Spring 和 Springboot 集成 實現(xiàn) JSON 和 XML 的序列化和反序列化 支持 JSON 轉換框架: Fastjson,Jackson, Gson 支持 JAXB 形式的 XML 轉換 支持 SSL 的單向和雙向加密 支持 http 連接池的設定 可以通過 OnSuccess 和 OnError 接口參數(shù)實現(xiàn)請求結果的回調 配置簡單,一般只需要 @Request 一個注解就能完成絕大多數(shù)請求的定義 支持異步請求調用
4. 兩個很棒的功能
4.1 模板表達式和參數(shù)的映射綁定功能
@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
);
@Request(
????url?=?"${base}/pay",
???contentType?=?"application/json",
????type?=?"post",
????dataType?=?"json",
????headers?=?{"Authorization:?${1}"},
????data?=?"${json($0)}"
)
public?PayResponse?pay(PayRequest?request,?String?auth);
4.2 對 HTTPS 的支持
@Request(
????url?=?"${base}/pay",
???contentType?=?"application/json",
????type?=?"post",
????dataType?=?"json",
???keyStore?=?"pay-keystore",
???data?=?"${json($0)}"
)
public?PayResponse?pay(PayRequest?request);
forest:
??...
??ssl-key-stores:
????-?id:?pay-keystore
??????file:?test.keystore
??????keystore-pass:?123456
??????cert-pass:?123456
??????protocols:?SSLv3
5. 最后
我整理了一份很全的學習資料,感興趣的可以微信搜索?「猿天地?」,回復關鍵字 「學習資料?」獲取我整理好了的Spring Cloud,Spring Cloud Alibaba,Sharding-JDBC分庫分表,任務調度框架XXL-JOB,MongoDB,爬蟲等相關資料。
后臺回復?學習資料?領取學習資料
如有收獲,點個在看,誠摯感謝
