本文主要介绍Java exploration中feign的引入。第一次遇到feign,所以在网上搜集了相关文章。本文比较详细,介绍了其简介,选择Feign的原因等相关内容。有需要的朋友可以参考一下。
一,简介
Feign让Java HTTP客户端编写更加方便。Feign的灵感来源于retrieval、JAXRS-2.0和WebSocket。Feign最初的设计是为了降低将分母统一绑定到HTTP API的复杂性,不管是否支持Restful。Feign的目标是用最少的资源和代码连接HTTP API。通过可定制的解码器和错误处理,您可以编写任何HTTP API。
Maven依赖于:
!-https://mvn repository . com/artifact/com . Netflix . feign/feign-core-
属国
groupIdcom.netflix.feign/groupId
artifactIdfeign-core/artifactId
版本8 . 18 . 0/版本
范围运行时间/范围
/依赖关系
二,为什么选择Feign而不是其他
您可以使用Jersey和CXF为Rest或SOAP服务编写一个java客户端。也可以直接使用Apache HttpClient。但Feign的目的是尽可能减少资源和代码来实现与HTTP API的连接。您可以通过自定义编解码器和错误处理来编写任何基于文本的HTTP API。
假装工作机制
Feign通过注入带有注释的模板请求来工作。发送前关闭即可,参数可直接应用于模板。但是,这也限制了Feign,它只支持文本API,这大大简化了系统对请求的响应。同时,进行单元测试也非常容易。
三,Feign使用简介
3.1,基本用法
的基本用途如下,一个典型改型样本的改编。
接口GitHub {
//RequestLine注释声明请求方法和地址,可以允许查询参数。
@ request line(' GET/repos/{ owner }/{ repo }/contributors ')
list contributor contributors(@ Param(' owner ')字符串所有者,@Param('repo ')字符串repo);
}
静态类贡献者{
字符串登录;
利息捐款;
}
公共静态void main(字符串.args) {
GitHub github=Feign.builder()。解码器(新的GsonDecoder())。target(GitHub.class,' https://API . github . com ');
//获取并打印该库的参与者列表。
list contributor contributors=github . contributors(' open feign ',' feign ');
对于(贡献者贡献者:贡献者){
system . out . println(contributor . log in '(' contributor . contributions '));
}
}
3.2,自定义
Feign有很多方面可以定制。举个简单的例子,您可以使用Feign.builder()用自己的组件构建一个API接口。如下所示:
接口库{
@ request line(' POST/account/{ id } ')
account getAccountInfo(@ Param(' id ')字符串id);
}
.
//AccountDecoder()是自己实现的解码器。
Bank bank=Feign.builder()。解码器(新的AccountDecoder())。target(Bank.class,https://API . example bank . com);
3.3,多种接口
Feign可以提供各种API接口,所有这些接口都被定义为TargetT(默认实现是HardCodedTargetT),它允许在执行请求之前动态发现和修饰请求。
例如,以下模式允许用当前url和身份验证令牌来修饰对身份验证中心服务的每个请求。
CloudDNS cloudDNS=Feign.builder()。target(new CloudIdentityTargetCloudDNS(user,API key));
例子
Feign包括GitHub和Wikipedia客户端的实现示例。类似的项目在实践中也使用Feign。尤其是它的示例守护程序。
第四,假装集成模块
Feign可以与其他开源工具集成。您可以将这些开源工具集成到Feign中。一些现有模块如下:
4.1,Gson
Gson包括一个编码器和一个解码器,可以用于JSON格式的API。
将GsonEncoder和GsonDecoder添加到您的外观中。构建器如下:
GsonCodec编解码器=new GsonCodec();
GitHub github=Feign.builder()。编码器(新GsonEncoder())。解码器(新的GsonDecoder())。目标(GitHub.class,https://API。github。com);
专家依赖:
!-https://mvn存储库。com/artifact/com。网飞。假装/假装——
属国
groupIdcom.netflix.feign/groupId
artifactIdfeign-gson/artifactId
版本8 .18 .0/版本
/依赖关系
4.2,Jackson
杰克逊包含了一个编码器和一个解码器,这个可以被用于JSON格式的API。
添加杰克逊编码器以及杰克逊解码器到你的假装。建设者中,如下:
GitHub github=Feign.builder()。编码器(新的JacksonEncoder())。解码器(新的JacksonDecoder())。目标(GitHub.class,https://API。github。com);
专家依赖:
!-https://mvn存储库。com/artifact/com。网飞。假装/假装——
属国
groupIdcom.netflix.feign/groupId
artifactIdfeign-Jackson/artifactId
版本8 .18 .0/版本
/依赖关系
4.3,Sax
萨克斯管解码器用于解析XML,并兼容普通虚拟机(Java虚拟机的缩写)和安卓系统。下面是一个配置萨克斯管来解析响应的例子:
api=Feign.builder()。解码器(SAXDecoder.builder()。registerContentHandler(userid处理程序。类)。build())。target(Api.class,https://API主机);
专家依赖:
属国
groupIdcom.netflix.feign/groupId
artifactIdfeign-sax/artifactId
版本8 .18 .0/版本
/依赖关系
4.4,JAXB
JAXB包含了一个编码器和一个解码器,这个可以被用于可扩展标记语言格式的API。
添加JAXBEncoder以及JAXBDecoder到你的假装。建设者中,如下:
api=Feign.builder()。编码器(新的JAXBEncoder())。解码器(新的JAXBDecoder())。target(Api.class,https://API主机);
专家依赖:
!-https://mvn存储库。com/artifact/com。网飞。假装/假装——
属国
groupIdcom.netflix.feign/groupId
artifactIdfeign-JAXB/artifactId
版本8 .18 .0/版本
/依赖关系
4.5,JAX-RS
JAXRSContract使用JAX遥感中心规范重写覆盖了默认的注解处理。下面是一个使用JAX遥感中心的例子:
接口GitHub {
@ GET @ Path('/repos/{ owner }/{ repo }/contributors ')
列出贡献者贡献者(@ path param(' owner ')字符串所有者,@PathParam('repo ')字符串回购);
}
//合同方法配置注解处理器,注解处理器定义了哪些注解和值是可以作用于接口的
GitHub github=Feign.builder()。契约(新的JAXRSContract())。目标(GitHub.class,https://API。github。com);
专家依赖:
!-https://mvn存储库。com/artifact/com。网飞。假装/假装——
属国
groupIdcom.netflix.feign/groupId
artifactIdfeign-jaxrs/artifactId
版本8 .18 .0/版本
/依赖关系
4.5,OkHttp
OkHttpClient使用OkHttp来发送假装的请求,OkHttp支持SPDY (SPDY是谷歌开发的基于传输控制协议(传输控制协议)的传输层协议,用以最小化网络延迟,提升网络速度,优化用户的网络使用体验),并有更好的控制超文本传送协议(超文本传输协议的缩写)请求。
要让假装使用OkHttp,你需要将OkHttp加入到你的环境变量中区,然后配置假装使用OkHttpClient,如下:
GitHub github=Feign.builder()。客户端(新的OkHttpClient())。目标(GitHub.class,' https://API。github。com’);
专家依赖:
!-https://mvn存储库。com/artifact/com。网飞。假装/假装——
属国
groupIdcom.netflix.feign/groupId
artifactIdfeign-ok http/artifactId
版本8 .18 .0/版本
/依赖关系
4.6,Ribbon
带状物客户端重写了假装客户端的对统一资源定位器的处理,其添加了智能路由以及一些其他由带状物提供的弹性功能。
集成带状物需要你将带状物的客户端名称当做全球资源定位器(统一资源定位器)的宿主部分来传递,如下:
//myAppProd是你的功能区客户端名称
MyService api=Feign.builder().客户端(RibbonClient.create()).target(MyService.class,' https://my approd ');
专家依赖:
!-https://mvn存储库。com/artifact/com。网飞。假装/假装——
属国
groupIdcom.netflix.feign/groupId
artifactIdfeign-ribbon/artifactId
版本8 .18 .0/版本
/依赖关系
4.7,Hystrix
HystrixFeign配置了高起鳞癣提供的熔断机制。
要在假装中使用海斯特里克斯,你需要添加高起鳞癣模块到你的环境变量,然后使用HystrixFeign来构造你的API:
我的服务API=hystrixfeign。构建器().target(MyService.class,' https://my approd ');
专家依赖:
!-https://mvn存储库。com/artifact/com。网飞。假装/假装——
属国
groupIdcom.netflix.feign/groupId
artifactId假子宫/artifactId
版本8 .18 .0/版本
/依赖关系
4.8,SLF4J
slf4j模块允许你使用SLF4J作为假装的日志记录模块,这样你就可以轻松的使用Logback,Log4J,等来记录你的日志。
要在假装中使用SLF4J,你需要添加SLF4J模块和对应的日志记录实现模块(比如Log4J)到你的环境变量,然后配置假装使用Slf4jLogger:
GitHub github=Feign.builder()。记录器(新的Slf4jLogger())。目标(GitHub.class,' https://API。github。com’);
专家依赖:
!-https://mvn存储库。com/artifact/com。网飞。假装/假装——
属国
groupIdcom.netflix.feign/groupId
artifactIdfeign-slf4j/artifactId
版本8 .18 .0/版本
/依赖关系
五,Feign 组成
5.1,Decoders
Feign.builder()允许你自定义一些额外的配置,比如说如何解码一个响应。假如有接口方法返回的消息不是响应,字符串,字节[]或者空的类型的,那么你需要配置一个非默认的解码器。
下面是一个配置使用JSON解码器(使用的是假想敌扩展)的例子:
GitHub github=Feign.builder()。解码器(新的GsonDecoder())。目标(GitHub.class,https://API。github。com);
假如你想在将响应传递给解码器处理前做一些额外的处理,那么你可以使用mapAndDecode方法。一个用例就是使用jsonp服务的时候:
//貌似1.8.0版本中沒有mapAndDecode这个方法。
JSON API JSON API=feign。构建器()。mapAndDecode((响应,类型)- jsopUnwrap(响应,类型),新的GsonDecoder())。目标(JSON API。类,https://some-jsonp-API。com);
5.2,Encoders
发送一个邮政请求最简单的方法就是传递一个线或者字节[]类型的参数了。你也许还需添加一个内容类型请求头,如下:
界面登录客户端{
@RequestLine('POST /')
@ Headers(' Content-Type:application/JSON ')
空的登录(字符串内容);
}
.
client.login('{ '用户名':'分母','密码':'秘密' } ');
通过配置一个解码器,你可以发送一个安全类型的请求体,如下是一个使用假想敌扩展的例子:
静态类凭据{
最终字符串用户名;
最终字符串密码;
凭据(字符串用户名,字符串密码){
this .用户名=用户名;
this.password=密码;
}
}
界面登录客户端{
@RequestLine('POST /')
无效登录(凭证creds);
}
.
登录客户端client=feign。构建器()。编码器(新GsonEncoder())。target(LoginClient.class,' https://foo。com’);
客户端登录(新凭据('分母','秘密'));
5.3,@Body templates
@Body注解申明一个请求体模板,模板中可以带有参数,与方法中@Param注解申明的参数相匹配,使用方法如下:
界面登录客户端{
@RequestLine('POST /')
@Headers('内容类型:应用程序/XML’)
@Body('登录'用户名'=' {用户名} ' '密码'=' {密码}'/')
void xml(@Param('user_name ')字符串用户,@Param('password ')字符串密码);
@RequestLine('POST /')
@ Headers(' Content-Type:application/JSON ')
//json大括号必须转义!
//这里JSON格式需要的花括号居然需要转码,有点蛋疼了。
@Body('{ '用户名':' {用户名} ','密码':' {密码}'} ')
void json(@Param('user_name ')字符串用户,@Param('password ')字符串密码);
}
.
client.xml('分母','秘密');//登录'用户名'='分母' '密码'='秘密'/
client.json('分母','秘密');//{ '用户名':'分母','密码':'秘密' }
5.4,Headers
假装支持给请求的美国石油学会(美国石油协会)设置或者请求的客户端设置请求头,如下:
给应用程序接口设置请求头
使用@标题设置静态请求头
//给BaseApi中的所有方法设置接受请求头
@ Headers(' Accept:application/JSON ')
接口基础ApiV {
//单独给放方法设置内容类型请求头
@ Headers(' Content-Type:application/JSON ')
@RequestLine('PUT /api/{key} ')
void put(@Param('key ')字符串,五值);
}
设置动态值的请求头
@RequestLine('POST /')
@Headers('X-Ping: {token} ')
void post(@Param('token ')字符串标记);
设置键和价值都是动态的请求头
有些应用程序接口需要根据调用时动态确定使用不同的请求头(例如诸如" x-amz-meta-"或“x-goog-meta——”的定制元数据头字段),
这时候可以使用@HeaderMap注解,如下:
//@HeaderMap注解设置的请求头优先于其他方式设置的
@RequestLine('POST /')
void post(@HeaderMap MapString,对象头映射);
给Target设置请求头
有时我们需要在一个应用程序接口实现中根据不同的端点来传入不同的标题,这个时候我们可以使用自定义的请求拦截器或目标来实现。
通过自定义的请求拦截器来实现请查看请求拦截器章节。
下面是一个通过自定义目标来实现给每个目标设置安全校验信息页眉的例子:
静态类DynamicAuthTokenTargetT实现TargetT {
public DynamicAuthTokenTarget(class t clazz,
UrlAndTokenProvider提供程序,
ThreadLocalString requestid提供程序);
.
@覆盖
公共请求应用(请求模板输入){
TokenIdAndPublicURL urlAndToken=provider。get();
if (input.url().indexOf('http ')!=0) {
input.insert(0,urlandtoken。公开网址);
}
input.header('X-Auth-Token ',urlandtoken。token id);
input.header('X-Request-ID ',请求ID提供者。get());
返回输入。请求();
}
}
.
Bank bank=Feign.builder()。target(new DynamicAuthTokenTarget(bank。类、提供者、请求id提供者));
这种方法的实现依赖于给假装客户端设置的自定义的请求拦截器或目标。可以被用来给一个客户端的所有美国石油学会(美国石油协会)请求设置请求头。比如说可是被用来在页眉中设置身份校验信息。这些方法是在线程执行美国石油学会(美国石油协会)请求的时候才会执行,所以是允许在运行时根据上下文来动态设置页眉的。
比如说可以根据线程本地存储(线程本地存储)来为不同的线程设置不同的请求头。
六,高级用法
6.1,基本应用程序接口
有些请求中的一些方法是通用的,但是可能会有不同的参数类型或者返回类型,这个时候可以这么用:
//通用应用程序接口
接口基础API {
@RequestLine('GET /health ')
string health();
@RequestLine('GET /all ')
列出实体all();
}
//继承通用应用程序接口
接口自定义API扩展了BaseAPI {
@RequestLine('GET /custom ')
string custom();
}
//各种类型有相同的表现形式,定义一个统一的应用程序接口
@ Headers(' Accept:application/JSON ')
接口基础ApiV {
@RequestLine('GET /api/{key} ')
V get(@Param('key ')字符串键);
@RequestLine('GET /api ')
ListV list();
@ Headers(' Content-Type:application/JSON ')
@RequestLine('PUT /api/{key} ')
void put(@Param('key ')字符串键,五值);
}
//根据不同的类型来继承
接口FooApi扩展了BaseApiFoo { }
接口巴拉皮扩展了BaseApiBar { }
6.2,Logging
你可以通过设置一个记录器来记录超文本传送协议(超文本传输协议的缩写)消息,如下:
GitHub github=Feign.builder()。解码器(新的GsonDecoder())。记录器(新记录器JavaLogger().appendToFile('logs/http.log '))。日志级别(记录器。水平。满)。目标(GitHub.class,https://API。github。com);
也可以参考上面的SLF4J章节的说明
6.3,Request Interceptors
当你希望修改所有的的请求的时候,你可以使用请求拦截器。比如说,你作为一个中介,你可能需要为每个请求设置x-转发-用于
静态类ForwardedForInterceptor实现RequestInterceptor {
@覆盖公共空的应用(请求模板模板){
模板。标题(' X-forward-For ',' origin。主持人。com’);
}
}
.
Bank bank=Feign.builder()。解码器(帐户解码器)。请求拦截器(新的ForwardedForInterceptor())。目标(Bank.class,https://API。示例银行。com);
或者,你可能需要实现基本身份验证,这里有一个内置的基础校验拦截器
基本请求拦截器
Bank bank=Feign.builder()。解码器(帐户解码器)。请求拦截器(新的基本请求拦截器(用户名,密码))。目标(Bank.class,https://API。示例银行。com);
6.4,自定义@Param扩展
在使用@Param注解给模板中的参数设值的时候,默认的是使用的对象的toString()方法的值,通过声明自定义的参数。扩展器,用户可以控制其行为,比如说格式化日期类型的值:
//通过设置@Param的膨胀器为DateToMillis.class可以定义日期类型的值
@RequestLine('GET /?自={date} ')
结果列表(@Param(value='date ',expander=datetomillis。类)日期日期);
6.5,Dynamic Query Parameters
动态查询参数支持,通过使用@QueryMap可以允许动态传入请求参数,如下:
@RequestLine('获取/查找)
V find(@QueryMap MapString,对象查询映射);
6.6,Static and Default Methods
如果你使用的是JDK 1.8的话,那么你可以给接口设置统一的默认方法和静态方法,这个事JDK8的新特性,如下:
接口GitHub {
@请求行('获取/回购/{所有者}/{回购}/贡献者')
列出贡献者贡献者(@ Param(' owner ')字符串所有者,@Param('repo ')字符串回购);
@请求行(' GET/users/{ username }/repos?sort={sort} ')
ListRepo repos(@Param('username ')字符串所有者,@Param('sort ')字符串排序);
默认列表回购(字符串所有者){
返回回购(所有者,'全名');
}
/**
*列出用户拥有的所有回购的所有参与者。
*/
默认列表贡献者贡献者(字符串用户){
合并贡献者列表贡献者=新合并贡献者列表();
对于(回购Repo:这个。回购(所有者)){
贡献者。addall(这个。贡献者(用户,回购。getname()));
}
回报贡献者。合并结果();
}
静态GitHub connect() {
return Feign.builder()。解码器(新的GsonDecoder())。目标(GitHub.class,' https://API。github。com’);
}
}
总结
以上就是本文关于Java 语言(一种计算机语言,尤用于创建网站)语言(一种计算机语言,尤用于创建网站)探索之假装入门使用详解的全部内容,希望对大家有所帮助。感兴趣的朋友可以继续参阅本站:Java编程几个循环实例代码分享、Java面向对象编程(封装/继承/多态)实例解析等,如有不足之处,欢迎留言指出。感谢朋友们对本站的支持!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。