一个看起来还挺不错的http框架,直接赋予接口请求链接,有点像feign?
作者:元人部落
转自:www.cnblogs.com/bryan31/p/13359376.html
因为业务关系,要和许多不同第三方公司进行对接。这些服务商都提供基于 http 的 api。但是每家公司提供 api 具体细节差别很大。有的基于 RESTFUL 规范,有的基于传统的 http 规范;有的需要再 header 里放置签名,有的需要 SSL 的双向认证,有的只需要 SSL 的单向认证;有的以 JSON 方式进行序列化,有的以 XML 方式进行序列化。类似于这样细节的差别太多了。
不同的公司 API 规范不一样,这很正常。但是对于我来说,我如果想要代码变得优雅。我就必须解决一个痛点:
我当然知道有很多优秀的大名鼎鼎的 http 开源框架可以实现任何形式的 http 调用,在多年的开发经验中我都有使用过。比如 apache 的 httpClient 包,非常优秀的 Okhttp,jersey client。
这些 http 开源框架的接口使用相对来说,都不太一样。不管选哪个,在我这个场景里来说,我都不希望在调用每个第三方的 http api 时写上一堆 http 调用代码。
所以,在这个场景里,我得对每种不同的 http api 进行封装。这样的代码才能更加优雅,业务代码和 http 调用逻辑耦合度更低。
可惜,我比较懒。一来觉得封装起来比较费时间,二来觉对封装这种底层 http 调用来说,应该有更好的选择。不想自己再去造轮子。
https://gitee.com/dt_flys/forest
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 和返回。当然日志可以通过配置去控制开关。
我觉得对于尤其是做对接第三方 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 一个注解就能完成绝大多数请求的定义
支持异步请求调用
这里不对使用方式和配置方式一一描述,有兴趣的可以去阅读详细文档:
https://dt_flys.gitee.io/forest 这里只想分析这个框架 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
(完)
MarkerHub文章索引:(点击阅读原文直达)
https://github.com/MarkerHub/JavaIndex
【推荐阅读】
线程异常如何处理?试试这样
写个日志请求切面,前后端甩锅更方便
从LocalDateTime序列化探讨全局一致性序列化
还在手动部署springboot项目?不妨试试它,让你部署项目飞起来!
为什么大家都说 SELECT * 效率低
Up主发表新教程啦,SpringBoot入门到精通!
好文章!点个在看!