0%

Feign调用问题

针对使用Feign远程调用的使用列出了一些开发中遇到的问题。

一、不能用ResponseEntity接收Feign的响应结果

  • 这次做的项目是以spring的全局响应对象ResponseEntity做的,最开始在Feign中也使用了ResponseEntity作为响应接收实体,于是发了请求之后一直显示发送请求中…,最后报了如下错误:
1
2
3
4
5
6
reactor.netty.http.client.PrematureCloseException: Connection prematurely closed DURING response
Suppressed: reactor.core.publisher.FluxOnAssembly$OnAssemblyException:
Error has been observed at the following site(s):
|_ checkpoint ⇢ org.springframework.cloud.gateway.filter.WeightCalculatorWebFilter [DefaultWebFilterChain]
|_ checkpoint ⇢ HTTP GET "/isrpUser/t/testfeign/1" [ExceptionHandlingWebHandler]
Stack trace:

最后打断点发现请求能进入controller层,之后一直在循环调用方法,在堆栈中来回循环,找不到service层最后超时异常。

二、超时时间

1
2
3
4
Feign.RetryableException: Read timed out executing GET http://isrp-user/isrpUser/isrpUser/emailInner/xxxx%40163.com
...
Caused by: java.net.SocketTimeoutException: Read timed out
...
  • 解决办法:设置超时时间
1
2
3
4
5
6
feign:  
client:
config:
default:
connect-timeout: 5000
read-timeout: 5000

三、在SpringSecurity之类的安全框架中使用feign问题

  • 如果需要在当前模块引用访问当前模块的FeignClient,在configure(WebSecurity web)里配置后在userDetailsService()里调用FeignClient不生效会被拦截,在userDetailsService()只允许调用当前模块的service。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 错误示例
@Override
protected UserDetailsService userDetailsService() {
return username -> {
SysUserDetails user = JSON.parseObject(JSON.toJSONString(userClient.queryByEmail(username)), SysUserDetails.class);
if(null != user) {
return user;
}
return null;
};
}
@Override
public void configure(WebSecurity web) throws Exception {
web.ignoring().antMatchers(
"/isrpUser/queryByEmail",
);
}

四、Feign的post只能有一个@RequestBody参数

  • feign和普通的spring的post一样,post请求只能有一个@RequestBody参数,否则会报如下异常。
1
Nested exception is java.lang.IllegalStateException: Method has too many Body parameters。

五、实体字段格式映射问题

  • 在SpringBoot项目中对实体进行注解格式化操作,将LocalDateTime的类型转成了 “yyyy-MM-dd HH:mm:ss”的字符串,通过FeignClient进行接收是会产生字段不匹配的问题。

    解决方法

    1. 可以将注解删掉,但是会影响SpringBoot项目给前端的反馈效果。
    2. 将实体转换成Map类型,在用Map对实体进行字段映射的序列化转换就可以解决报错了。