如果你因为业务关系需要对接很多不同的第三方公司。这些服务提供商都提供基于http的API。但是,每个公司提供的API的具体细节差异很大。有的基于RESTFUL规范,有的基于传统的http规范;有的需要在header中放置签名,有的需要SSL双向认证,有的只需要SSL单向认证;有的以JSON方式序列化,有的以XML方式序列化。像这样的细节差别太多了。不同的公司有不同的API规范,这是正常的。但是对于我来说,如果我希望代码优雅。我要解决一个痛点:不同服务商的API差异那么大,如何维护一套不涉及业务的公共http调用套件。最好通过配置或者简单的参数来区分。打电话方便吗?我当然知道有很多优秀的、知名的http开源框架,可以实现任意形式的http调用,在多年的开发经验中都使用过。比如Apache的httpClient包,很不错的Okhttp,jerseyclient。这些http开源框架的接口用法都比较不一样。不管你选择哪一种,在我的场景下,我不想在调用每一个第三方httpapi的时候写一堆http调用代码。所以,在这种情况下,我必须打包每个不同的httpapi。只有这样的代码才能更优雅,业务代码和http调用的逻辑耦合度更低。不幸的是,我很懒惰。一方面,我认为封装起来需要更多的时间,另一方面,我认为封装这种底层的http调用应该有更好的选择。我不想自己重新发明轮子。于是,我找到了一个优秀的开源http框架,可以屏蔽所有httpapi细节不同带来的差异。它可以像调用rpc框架一样通过简单的配置完成极其复杂的http调用。https://gitee.com/dromara/forest入门Forest支持Springboot的自动组装,所以只需要引入一个依赖com.dtflys.forestspring-boot-starter-forest1.3.0```java定义了自己的接口类publicinterfaceMyClient{@Request(url="http://baidu.com")StringsimpleRequest();@Request(url="http://ditu.amap.com/service/regeo",dataType="json")MapgetLocation(@DataParam("longitude")Stringlongitude,@DataParam("latitude")Stringlatitude);}在在启动类中配置代理接口类的扫描包```jva@SpringBootApplication@ForestScan(basePackages="com.example.demo.forest")publicclassDemoApplication{publicstaticvoidmain(String[]args){SpringApplication.run(DemoApplication.class,args);}}此时,您可以从spring容器中注入您的代理接口,并像本地方法一样调用httpapi@AutowiredprivateMyClientmyClient;@OverridepublicvoidyourMethodthrowsException{Mapresult=myClient.getLocation("124.730329","31.463683");System.out.println(JSON.toJSONString(result,true));}日志打印,Forest打印内部使用的httpframe,以及实际请求的url和返回。当然日志可以配置控制开关的功能我觉得这个开源框架可以帮助大家提高很多效率,特别是对于开发第三方API的同学,Forest底层封装了两个不同的http框架:ApachehttpClient和OKhttp。所以这个开源框架并没有在底层实现上重新发明轮子,而是在易用性上下了很多功夫,我用Forest最终完成了对接多个服务商API的项目,这些API我只花了1个小时不同的样式,转换成本地的方法,然后项目就顺利上线了。forest是一个更高层次的http框架,其实不需要写很多代码。大部分时候,你就可以完成http只有本地化调用一些配置。但是这个框架可以覆盖的范围非常广,可以满足你绝大部分的http调用请求。Forest有以下特点:以Httpclient和OkHttp为后端框架,通过调用本地方法发送Http请求,实现业务逻辑与Http协议的解耦相比Feign,更轻量,不依赖SpringCloud和任意注册中心支持所有请求方式:GET、HEAD、OPTIONS、TRACE、POST、DELETE、PUT、PATCH支持灵活的模板表达式支持过滤器过滤传入数据基于注解和配置定义Http请求支持Spring和Springboot集成JSON和XML序列化和反序列化支持JSON转换框架:Fastjson、Jackson、Gson支持JAXB形式的XML转换支持SSL单向和双向加密支持http连接池设置可以通过OnSuccess和OnError接口参数设置回调配置来实现请求结果很简单。一般只需要一个@Request注解就可以完成大部分请求的定义。支持异步请求调用。这里不描述两个很棒的功能。有兴趣的可以去阅读详细的文档:http://forest.dtflyx.com/这里我只是想分析一下这个框架。我认为它是一个很好的函数模板表达式和参数映射。绑定函数模板表达式,使用的时候非常方便。例如栗子@Request(url="${0}/send?un=${1}&pw=${2}&ph=${3}&ct=${4}",type="get",dataType=“json”)publicMapsend(Stringbase,StringuserName,Stringpassword,Stringphone,Stringcontent);上面是使用序号下标取值,也可以使用名称取值:@Request(url="${base}/send?un=${un}&pw=${pw}&ph=${3}&ct=${ct}",type="get",dataType="json")publicMapsend(@DataVariable(“base”)Stringbase,@DataVariable(“un”)StringuserName,@DataVariable(“pw”)Stringpassword,@DataVariable(“ph”)Stringphone,@DataVariable(“ct”)Stringcontent);even可以这样简化:@Request(url="${base}/send",type="get",dataType="json")publicMapsend(@DataVariable("base")Stringbase,@DataParam("un")StringuserName,@DataParam("pw")Stringpassword,@DataParam("ph")Stringphone,@DataParam("ct")Stringcontent);以上三种写法是等价的,当然你也可以把参数绑定到header和body上去,你甚至可以简单的把对象序列化成json或者xml,用一些表达式:@Request(url="${base}/pay",contentType="application/json",type="post",dataType="json",headers={"Authorization:${1}"},data="${json($0)}")publicPayResponsepay(PayRequestrequest,字符串验证);当然,关于数据绑定的细节可以参考文档SupportforHTTPS以前用其他http框架处理https的时候,总觉得很麻烦,尤其是遇到双向证书的问题,只好去百度了。然后根据别人的经验修改自己的代码。Forest在这方面也考虑的很周到,底层完美封装了对https单向和双向证书的支持。也可以通过简单的配置快速完成。举个双向证书例子:@Request(url="${base}/pay",contentType="application/json",type="post",dataType="json",keyStore="pay-keystore",data="${json($0)}")publicPayResponsepay(PayRequestrequest);其中pay-keystore对应于application.yml中的ssl-key-storesforest:...ssl-key-stores:-id:pay-keystorefile:test。keystorekeystore-pass:123456cert-pass:123456protocols:SSLv3这样设置就ok了,剩下的以本地代码的形式调用。最后,Forest还有很多其他的功能设置。如果您有兴趣,请仔细阅读文档和示例。不过我想说的是,相信很多人看到这里之后肯定会说,这不是Feign吗?我在开发SpringCloud项目的时候,也用过一段时间Feign。个人感觉Forest在配置和使用上确实和Feign的设计很相似,但是Feign的作用更多的是作为SpringCloud生态中的一员。扮演RPC通信的角色,不仅承担http通信,还承担注册中心下发的调用地址的负载均衡。Forest,一个开源项目,定位为高级http工具,主打友好易用。从使用的角度来说,个人觉得Forest的配置更简单直接。提供的很多功能也可以解决很多人的痛点。开源精神值得称道,好的开源需要大家的贡献和支持。希望这篇文章能给你在选择http客户端框架时带来新的选择:Forest