Feign 自定义编码器、解码器和客户端
Feign 的编码器、解码器和客户端都是支持自定义扩展,可以对请求以及结果和发起请求的过程进行自定义实现,Feign 默认支持 JSON 格式的编码器和解码器,如果希望支持其他的或者自定义格式就需要编写自己的编码器和解码器,如果希望编写自己的编码器,需要实现 feign.codec.Encoder 接口,解码器需要实现 feign.codec.Decoder 接口,示例如下:
自定义编码器和解码器
- 自定义编码器
实现的自定义编码器只是输出了需要编码的参数信息,而具体的编码还是使用 JSON 格式,使用了 GsonEncoder 编码器来完成具体的编码工作,参数 object 表示需要进行编码的对象,参数 bodyType 为 object 对象的类型,参数 template 表示的就是请求模板,该方法就是需要实现将参数 object 进行编码并赋值到 template 请求模板中。
package org.lixue.feignclient;
import feign.RequestTemplate;
import feign.codec.EncodeException;
import feign.codec.Encoder;
import feign.gson.GsonEncoder;
import java.lang.reflect.Type;
public class MyEncoder implements Encoder{
private GsonEncoder gsonEncoder;
publicMyEncoder(){
gsonEncoder = new GsonEncoder();
}
public void encode(Object object,Type bodyType,RequestTemplate template) throws EncodeException{
System.out.println("encode object is class"+object.getClass().getName());
System.out.println("encode object is value"+object);
System.out.println("encode bodyType is class"+bodyType.getClass().getName());
System.out.println("encode bodyType is value"+bodyType);
gsonEncoder.encode(object,bodyType,template);
}
}
- 自定义解码器
实现的自定义解码器使用了 GsonDecoder 解码器来完成具体的编码工作,解码器相对简单,只需要从响应中获取响应报文,然后按照指定的编码格式相应的解码并创建指定的类型实例即可。
package org.lixue.feignclient;
import feign.FeignException;
import feign.Response;
import feign.codec.DecodeException;
import feign.codec.Decoder;
import feign.gson.GsonDecoder;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
public class MyDecoder implements Decoder{
private GsonDecoder gsonDecoder;
publicMyDecoder(){
gsonDecoder=newGsonDecoder();
}
public Object decode(Response response,Type type)throws IOException,DecodeException,FeignException{
return gsonDecoder.decode(response,type);
}
}
- 测试验证
在完成自定义编码器和解码器的开发后,只需要在 Feign 的 builder 方法中,增加解码器和编码器即可,需要注意的是,如果方法请求参数或返回的不是对象,不需要进行编码或解码,就不能增加编码器或解码器,示例代码如下:
package org.lixue.feignclient;
import feign.Feign;
import feign.Logger;
import feign.gson.GsonDecoder;
import feign.gson.GsonEncoder;
public class Startup{
public static void main(String[]args){
HelloWorldClient speakClient=
Feign.builder().target(HelloWorldClient.class,"http://localhost:8080/");
// 参数和返回都不是对象,不需要附加编码器和解码器
System.out.println(speakClient.speak("isbody"));
HelloWorldClient findByIdClient=
Feign.builder().decoder(new GsonDecoder())
.target(HelloWorldClient.class,"http://localhost:8080/");
// 返回的是对象,需要附加解码器
Person person=findByIdClient.findById(34);
System.out.println("personid="+person.getId()+"age="+person.getAge()+"name="+person.getName()+"message="+person.getMessage());
HelloWorldClient createClient=
Feign.builder().client(newMyClient())
.decoder(newMyDecoder())
.encoder(newMyEncoder())
.target(HelloWorldClient.class,"http://localhost:8080/");
Person newPerson=new Person();
newPerson.setId(3434);
newPerson.setAge(34);
newPerson.setName("343434");
newPerson.setMessage("33333333333333333");
// 参数和返回都是对象,需要附加解码器和编码器
ReturnValuereturnValue=createClient.create(newPerson);
System.out.println(returnValue.parseString());
}
}
自定义 Feign 客户端
- 自定义 Feign 客户端
Feign 使用一个 feign.Client 接口来发送请求,默认实现是使用 HttpURLConnection 连接 HTTP 服务,我们可以实现 feign.Client 接口来完成自定义 Feign 客户端的开发,该接口只有一个方法 execute ,用于执行请求,下面实现了一个自定义的 Feign 客户端,主要完成了请求的日志记录,示例代码如下:
package org.lixue.feignclient;
import feign.Client;
import feign.Request;
import feign.Response;
import java.io.IOException;
import java.util.Collection;
import java.util.Map;
public class MyClient implements Client{
public Response execute(Request request,Request.Options options)throws IOException{
System.out.println("execute request method="+request.method());
System.out.println("execute request headers");
Map<String,Collection<String>> headers=request.headers();
for(Map.Entry<String,Collection<String>> entry:headers.entrySet()){
StringBuilderstringBuilder=newStringBuilder();
for(intj=0;j<entry.getValue().size();j++){
if(stringBuilder.length()>0){
stringBuilder.append(",");
}
stringBuilder.append(entry.getValue());
}
System.out.println(entry.getKey()+":"+stringBuilder.toString());
}
byte[] body=request.body();
if(body!=null){
System.out.println("execute request body="+newString(body));
}
// 使用 Feign 默认的客户端请求
return new Client.Default(null,null).execute(request,options);
}
}
- 测试验证
和附加编码器、解码器类似,只需要在 Feign 的 builder 方法中附加自定义的客户端即可,代码如下:
package org.lixue.feignclient;
import feign.Feign;
import feign.Logger;
import feign.gson.GsonDecoder;
import feign.gson.GsonEncoder;
public class Startup{
public static void main(String[]args){
HelloWorldClient findByIdClient=
Feign.builder().client(new MyClient())
.decoder(new GsonDecoder())
.target(HelloWorldClient.class,"http://localhost:8080/");
Person person=findByIdClient.findById(34);
System.out.println("personid="+person.getId()+"age="+person.getAge()+"name="+person.getName()+"message="+person.getMessage());
}
}
Feign 自定义编码器、解码器和客户端的更多相关文章
- Feign 自定义编码器、解码器和客户端,Feign 转发请求头(header参数)、Feign输出Info级别日志
Feign 的编码器.解码器和客户端都是支持自定义扩展,可以对请求以及结果和发起请求的过程进行自定义实现,Feign 默认支持 JSON 格式的编码器和解码器,如果希望支持其他的或者自定义格式就需要编 ...
- Netty学习笔记(三) 自定义编码器
编写一个网络应用程序需要实现某种编解码器,编解码器的作用就是讲原始字节数据与自定义的消息对象进行互转.网络中都是以字节码的数据形式来传输数据的,服务器编码数据后发送到客户端,客户端需要对数据进行解码, ...
- Feign自定义编程配置
介绍 在Spring Cloud中,Feign的默认配置类是FeignClientsConfiguration,该类定义了Feigh默认使用的编码器.解码器.所使用的契约等.Spring Cloud允 ...
- Spring Cloud Feign 自定义配置(重试、拦截与错误码处理) 实践
Spring Cloud Feign 自定义配置(重试.拦截与错误码处理) 实践 目录 Spring Cloud Feign 自定义配置(重试.拦截与错误码处理) 实践 引子 FeignClient的 ...
- python之simplejson,Python版的简单、 快速、 可扩展 JSON 编码器/解码器
python之simplejson,Python版的简单. 快速. 可扩展 JSON 编码器/解码器 simplejson Python版的简单. 快速. 可扩展 JSON 编码器/解码器 编码基本的 ...
- 普适注意力:用于机器翻译的2D卷积神经网络,显著优于编码器-解码器架构
现有的当前最佳机器翻译系统都是基于编码器-解码器架构的,二者都有注意力机制,但现有的注意力机制建模能力有限.本文提出了一种替代方法,这种方法依赖于跨越两个序列的单个 2D 卷积神经网络.该网络的每一层 ...
- 12-低延迟、全接口(HMDI、DVI、YPb Pr、RGB)H.264全高清编码器解码器
低延迟.全接口(HMDI.DVI.YPb Pr.RGB)H.264全高清编码器解码器 一.产品介绍 1.近零延时的H.264压缩到1920x1080p60 该产品提供分辨率为1920x1080p6 ...
- 【干货】如何通过OPC自定义接口来实现客户端数据的读取?
上篇博文分享了我的知识库,被好多人关注,受宠若惊.今天我把我在项目中封装的OPC自定义接口的程序分享一下.下面将会简单简单介绍下OPC DA客户端数据访问,以及搭配整个系统的运行环境. OPC(OLE ...
- 自定义token,保存到客户端的cookie中,
自定义token #原理自定义token,放入cookie中,不用存数据库 #token定义方式 >>>>> "加密字符串"|登陆用户id|用户登陆时 ...
随机推荐
- 【Python】多线程-3
#练习:线程等待 Event e.set() e.wait() from threading import Thread, Lock import threading import time ...
- 日期和API
Java1.0对日期和时间的支持只能依赖java.util.Date类,年份的起始选择是1900你那,月份的起始是从0开始计算的.它的返回值中包含了JVM的默认市区CET,即中欧时间.在Java1.1 ...
- IK 中文分词器
链接:https://github.com/wks/ik-analyzerIKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包.从2006年12月推出1.0版开始,IKAna ...
- JAVA 第四章 数组
数组保存的是一组有顺序的.具有相同类型的数据. 1.创建: 数组的声明格式: int arrary[]; int [] array1, array2; //同时声明多个数组. 上面的语句只是对数组进行 ...
- Linux中ctrl+z,ctrl+d和ctrl+c的区别
Ctrl-c Kill foreground processCtrl-z Suspend foreground processCtrl-d Terminate input, or exit shell
- 【状压DP】【HDOJ1074】
http://acm.hdu.edu.cn/showproblem.php?pid=1074 Doing Homework Time Limit: 2000/1000 MS (Java/Others) ...
- java transient 知识点学习
今天看源码的时候看到这个关键字,完全没见过,不懂.好吧!学习一下. 我们都知道实现了Serilizable接口的类,便可以序列化,那么其中某些成员变量不想被序列化怎么办?就是利用transient这个 ...
- JAVA静态代码块的作用
一 般情况下,如果有些代码必须在项目启动的时候就执行的时候,需要使用静态代码块,这种代码是主动执行的;需要在项目启动的时候就初始化,在不创建对象的情 况下,其他程序来调用的时候,需要使用静态方法,这种 ...
- js判断输入的字符是否是汉字
<script type="text/javascript"> var c=prompt("请输入一个字符"); var isNumber = c& ...
- Spring通知方法错误
错误提示,主要最后一句话 ,花了2个小时 org.springframework.beans.factory.BeanCreationException: Error creating bean ...