<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一款直擊痛點的優(yōu)秀http框架,讓我超高效率完成了和第三方接口的對接

          共 4933字,需瀏覽 10分鐘

           ·

          2020-08-01 06:34

          來源:元人部落


          1.背景

          因為業(yè)務(wù)關(guān)系,要和許多不同第三方公司進行對接。這些服務(wù)商都提供基于http的api。但是每家公司提供api具體細節(jié)差別很大。有的基于RESTFUL規(guī)范,有的基于傳統(tǒng)的http規(guī)范;有的需要在header里放置簽名,有的需要SSL的雙向認證,有的只需要SSL的單向認證;有的以JSON?方式進行序列化,有的以XML方式進行序列化。類似于這樣細節(jié)的差別太多了。

          不同的公司API規(guī)范不一樣,這很正常。但是對于我來說,我如果想要代碼變得優(yōu)雅。我就必須解決一個痛點:

          不同服務(wù)商API那么多的差異點,如何才能維護一套不涉及業(yè)務(wù)的公共http調(diào)用套件。最好通過配置或者簡單的參數(shù)就能區(qū)分開來。進行方便的調(diào)用?

          我當然知道有很多優(yōu)秀的大名鼎鼎的http開源框架可以實現(xiàn)任何形式的http調(diào)用,在多年的開發(fā)經(jīng)驗中我都有使用過。比如apachehttpClient包,非常優(yōu)秀的Okhttpjersey client

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

          所以,在這個場景里,我得對每種不同的http api進行封裝。這樣的代碼才能更加優(yōu)雅,業(yè)務(wù)代碼和http調(diào)用邏輯耦合度更低。

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

          于是,我發(fā)現(xiàn)了一款優(yōu)秀的開源http框架,能屏蔽不同細節(jié)http api所帶來的所有差異。能通過簡單的配置像調(diào)用rpc框架一樣的去完成極為復(fù)雜的http調(diào)用。

          Forest(點擊文章末尾閱讀原文也可以直接跳轉(zhuǎn)到項目首頁)

          https://gitee.com/dt_flys/forest



          2.上手

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

          <dependency>
          ??<groupId>com.dtflys.forestgroupId>
          ??<artifactId>spring-boot-starter-forestartifactId>
          ??<version>1.3.0version>
          dependency>

          定義自己的接口類

          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容器中注入你的代理接口,像調(diào)用本地方法一樣去調(diào)用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打印了內(nèi)部所用的http框架,和實際請求url和返回。當然日志可以通過配置去控制開關(guān)。



          3.特點

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

          Forest?底層封裝了2種不同的http框架:Apache httpClientOKhttp。所以這個開源框架并沒有對底層實現(xiàn)進行重復(fù)造輪子,而是在易用性上面下足了功夫。

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

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

          Forest有以下特點:

          • HttpclientOkHttp為后端框架
          • 通過調(diào)用本地方法的方式去發(fā)送Http請求, 實現(xiàn)了業(yè)務(wù)邏輯與Http協(xié)議之間的解耦
          • 相比Feign更輕量,不依賴Spring Cloud和任何注冊中心
          • 支持所有請求方法:GET,?HEAD,?OPTIONS,?TRACE,?POST,?DELETE,?PUT,?PATCH
          • 支持靈活的模板表達式
          • 支持過濾器來過濾傳入的數(shù)據(jù)
          • 基于注解、配置化的方式定義Http請求
          • 支持SpringSpringboot集成
          • 實現(xiàn)JSONXML的序列化和反序列化
          • 支持JSON轉(zhuǎn)換框架:?Fastjson,Jackson,?Gson
          • 支持JAXB形式的XML轉(zhuǎn)換
          • 支持SSL的單向和雙向加密
          • 支持http連接池的設(shè)定
          • 可以通過OnSuccessOnError接口參數(shù)實現(xiàn)請求結(jié)果的回調(diào)
          • 配置簡單,一般只需要@Request一個注解就能完成絕大多數(shù)請求的定義
          • 支持異步請求調(diào)用

          4.兩個很棒的功能

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

          https://dt_flys.gitee.io/forest

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

          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
          )
          ;

          以上三種寫法是等價的

          當然你也可以把參數(shù)綁定到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);

          當然數(shù)據(jù)綁定這塊詳情請參閱文檔

          4.2 對HTTPS的支持

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

          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對應(yīng)著application.yml里的ssl-key-stores

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

          這樣設(shè)置,就ok了,剩下的,就是本地代碼形式的調(diào)用了。

          5.最后

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

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

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

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

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



          免費領(lǐng)取 1000+ 道面試資料!!小編這里有一份面試寶典《Java 核心知識點.pdf》,覆蓋了 JVM,鎖、高并發(fā)、Spring原理、微服務(wù)、數(shù)據(jù)庫、Zookeep人、數(shù)據(jù)結(jié)構(gòu)等等知識點,包含 Java 后端知識點 1000+ 個,部分如下:

          如何獲取?加小編微信,回復(fù)【1024】


          瀏覽 69
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国内精品久久久久久久久久 | 日韩欧美高清无码 | 欧美日韩一级二级三级 | 青娱乐成人电影 | 亚洲一区无码视频 |