一款直击痛点的优秀 HTTP 框架,让我超高效完成了第三方接口的对接
转自:www.cnblogs.com/bryan31/p/13359376.html
因为业务关系,要和许多不同第三方公司进行对接。这些服务商都提供基于 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 调用。
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));
}
日志打印,Forest 打印了内部所用的 http 框架,和实际请求 url 和返回。当然日志可以通过配置去控制开关。
3. 特点
我觉得对于尤其是做对接第三方 api 的开发同学来说,这款开源框架能帮你提高很多效率。
搜索公纵号:MarkerHub,关注回复[ vue ]获取前后端入门教程!
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 一个注解就能完成绝大多数请求的定义 支持异步请求调用
4. 两个很棒的功能
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
);
@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,爬虫等相关资料。
后台回复 学习资料 领取学习资料
如有收获,点个在看,诚挚感谢