feign 拦截器的作用
每次 feign 发起http调用之前,会去执行拦截器中的逻辑。
使用场景
- 统一添加 header 信息;
- 对 body 体中的信息做修改或替换;
接口定义
package feign;
public interface RequestInterceptor {
/**
* template 是对 http 的封装,可以拿到这次 http 的所有信息,比如:请求头、请求体。
*/
void apply(RequestTemplate template);
}
使用方法
public class CustomFeignRequestInterceptor implements RequestInterceptor{
@Override
public void apply(RequestTemplate template) {
// template 都拿到了,想做啥都行
}
}
// 注意此类不要交给spring管理,不然所有feign调用都会使用该配置,除非你就是想这样.
public class RequestInterceptorConfig {
@Bean
public RequestInterceptor customRequestInterceptor(){
return new CustomFeignRequestInterceptor();
}
}
@FeignClient(name = "RequestInterceptorTest",
// 指定config
configuration = RequestInterceptorConfig.class,
url = "http://localhost:${server.port}")
public interface FeignClient {
@PostMapping("test")
public void test();
}
// 完整代码见码云 : https://gitee.com/lisinian/feign-test
feign 编码器的作用
用来将 feign 接口定义的参数编码到请求体中。
例如一个 feign 接口定义如下 : public void send(@RequestBody User user);
,默认的spring编码器就会把该 user 类编成 json 格式放到请求体中。
使用场景
- 比如有的第三方接收 xml 格式的请求体,那就可以按需制定。
接口定义
package feign.codec;
public interface Encoder {
void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException;
}
以 public void send(@RequestBody User user)
为例来解释下 encode 方法参数的含义:
- object : 就是 user 这个对象;
- bodyType : 就是 object 的类型,在这里就是 com.xxx.User;
- template : 同上面讲的 RequestInterceptor 的 template 。
使用方法
public class CustomFeignEncoder implements Encoder {
@Override
public void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException {
// 你需要的东西都在,随便做什么啦
}
}
// 同样注意不要交给spring托管
public class EncoderConfig {
@Bean
public Encoder customEncoder(){
return new CustomFeignEncoder();
}
}
@FeignClient(name = "EncoderTest",
configuration = EncoderConfig.class,
url = "http://localhost:${server.port}")
public interface FeignClient {
@PostMapping("test")
void test(Order order);
}
// 完整代码见码云 : https://gitee.com/lisinian/feign-test
Feign 解码器的作用
将 http 调用返回的 response 解码成 feign 接口定义的返回类型。
以public Fruit test()
为例,就是把返回的http response 请求体中的内容解码成 Fruit 对象。
使用场景
- 将第三方返回的不规则请求体封装成自定义对象。
接口定义
package feign.codec;
public interface Decoder {
Object decode(Response response, Type type) throws IOException, DecodeException, FeignException;
}
- response 就是 http 请求返回的所有信息;
- type 就是 feign 接口定义的返回类型.
使用方法
public class CustomFeignDecoder implements Decoder {
@Override
public Object decode(Response response, Type type) throws IOException, DecodeException, FeignException {
byte[] bodyBytes = inputStream.readAllBytes();
String bodyStr = new String(bodyBytes, UTF_8);
// 之后根据body转成你想要的对象,比如body是 "success:154545" 格式,":"前面是请求结果,后面是流水号,那你就根据":"分割字符串,之后set进自己的对象里
}
}
// 同样注意不要交给spring托管
public class DecoderConfig {
@Bean
public Decoder customDecoder(){
return new CustomFeignDecoder();
}
}
@FeignClient(name = "DecoderTest",
configuration = DecoderConfig.class,
url = "http://localhost:${server.port}")
public interface FeignClient {
@PostMapping("test")
public Fruit test();
}
// 完整代码见码云 : https://gitee.com/lisinian/feign-test