引入jar包
<dependency>
<groupId>com.dtflys.forest</groupId>
<artifactId>spring-boot-starter-forest</artifactId>
<version>1.3.0</version>
</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容器中注入你的代理接口,像調用本地方法一樣去調用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和返回。當然日志可以通過配置去控制開關。
Forest
底層封裝了2種不同的http框架:Apache httpClient
和OKhttp
。所以這個開源框架並沒有對底層實現進行重復造輪子,而是在易用性上面下足了功夫。
我用Forest
最終完成了和多個服務商api對接的項目,這些風格迥異的API,我僅用了1個小時時間就把他們轉化為了本地方法。然后項目順利上線。
Forest
作為一款更加高層的http框架,其實你並不需要寫很多代碼,大多數時候,你僅通過一些配置就能完成http的本地化調用。而這個框架所能覆蓋的面,卻非常之廣,滿足你絕大多數的http調用請求。
Forest
有以下特點:
- 以
Httpclient
和OkHttp
為后端框架 - 通過調用本地方法的方式去發送Http請求, 實現了業務邏輯與Http協議之間的解耦
- 相比Feign更輕量,不依賴
Spring Cloud
和任何注冊中心 - 支持所有請求方法:
GET
,HEAD
,OPTIONS
,TRACE
,POST
,DELETE
,PUT
,PATCH
- 支持靈活的模板表達式
- 支持過濾器來過濾傳入的數據
- 基於注解、配置化的方式定義
Http
請求 - 支持
Spring
和Springboot
集成 - 實現
JSON
和XML
的序列化和反序列化 - 支持JSON轉換框架:
Fastjson
,Jackson
,Gson
- 支持
JAXB
形式的XML
轉換 - 支持
SSL
的單向和雙向加密 - 支持http連接池的設定
- 可以通過
OnSuccess
和OnError
接口參數實現請求結果的回調 - 配置簡單,一般只需要
@Request
一個注解就能完成絕大多數請求的定義 - 支持異步請求調用
詳細文檔: https://dt_flys.gitee.io/forest
4.1 模板表達式和參數的映射綁定功能
模板表達式在使用的時候特別方便,舉個栗子
@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);
當然數據綁定這塊詳情請參閱文檔
4.2 對HTTPS
的支持
以前用其他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了,剩下的,就是本地代碼形式的調用了。
原文鏈接: https://mp.weixin.qq.com/s/MGgd9yqMm1SC0pd2M6szJA