feign 調(diào)用常見(jiàn)問(wèn)題避坑指南!
你知道的越多,不知道的就越多,業(yè)余的像一棵小草!
你來(lái),我們一起精進(jìn)!你不來(lái),我和你的競(jìng)爭(zhēng)對(duì)手一起精進(jìn)!
編輯:業(yè)余草
juejin.cn/post/7132495545884639240
推薦:https://www.xttblog.com/?p=5353
寫(xiě)在前面
很多時(shí)候,我們?cè)谑褂梦⒎?wù)框架的時(shí)候,就基本上少不了與feign打交道。
畢竟服務(wù)之間的調(diào)用,基本上都不會(huì)用手寫(xiě)http工具類去調(diào)了,這樣顯得有點(diǎn)麻煩了,feign更方便了。
而且feign,還自帶了負(fù)載均衡的策略(ribbon提供),如果我們的服務(wù)是集群的,feign還能負(fù)載調(diào)用。
這些估計(jì)大家都懂吧?不會(huì)還有人不懂吧?那這個(gè)要深入學(xué)習(xí)了。
在用feign的日常中,難免會(huì)遇到些問(wèn)題,那下面,我來(lái)總結(jié)下,我司在項(xiàng)目開(kāi)發(fā)中遇到的問(wèn)題。
雖說(shuō)不是大問(wèn)題,但至少是點(diǎn)經(jīng)驗(yàn)分享,希望可以幫助到大家。當(dāng)然有些問(wèn)題可以通過(guò)升級(jí)到 openfeign 進(jìn)行輕松解決。
好啦,下面開(kāi)始嘍!!!

FEIGN 常見(jiàn)問(wèn)題
400 Bad Request 問(wèn)題
「問(wèn)題描述」
在使用feign調(diào)用的使用出現(xiàn)400 Bad request的問(wèn)題。
「代碼如下」
@PostMapping("/llsydn/getMenusByIdsAndTypes")
List<SysMenuDto> getMenusByIdsAndTypes(@RequestParam("menuIds") String menuIds,
@RequestParam("menuType") String menuType);
這個(gè) menuIds 數(shù)量比較多,導(dǎo)致400 錯(cuò)誤。發(fā)現(xiàn)問(wèn)題出在menuIds 跟在URL后面。
解決辦法
將方法修改為:
@PostMapping("/llsydn/getMenusByIdsAndTypes")
List<SysMenuDto> getMenusByIdsAndTypes(@RequestBody MultiValueMap<String,String> queryParam);
調(diào)用方法修改成:
public List<SysMenuDto> getMenusByIdsAndNotType(String menuIds, String menuType){
MultiValueMap valueMap=new LinkedMultiValueMap();
valueMap.add("menuIds",menuIds);
valueMap.add("menuType",menuType);
return systemClient.getMenusByIdsAndTypes(valueMap);
}
非法字符錯(cuò)誤
錯(cuò)誤信息
在系統(tǒng)調(diào)用系統(tǒng)腳本的接口的時(shí)候拋出如下的錯(cuò)誤。
Illegal character ((CTRL-CHAR, code 31)): only regular white space (\r, \n, \t) is allowed between tokens
錯(cuò)誤原因
是feign 調(diào)用的時(shí)候啟用了「壓縮」導(dǎo)致的。
解決辦法
關(guān)閉壓縮即可。

將配置改成:
feign.compression.request.enabled=false
feign.compression.response.enabled=false或者使用okHttp
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
字符串中文亂碼問(wèn)題
錯(cuò)誤信息
在Feign調(diào)用時(shí),傳到目標(biāo)服務(wù)的方法中,字符串里的中文變成問(wèn)號(hào)了
解決辦法
在Feign的接口的注解中指定consumes字符集:
@PostMapping(value = "/portal/core/appdata/install",consumes = "application/json;charset=UTF-8")
void install(@RequestBody String data);
如果此時(shí)data為[{},{}]格式的JSON字符串,即JSON數(shù)組字符串,又會(huì)報(bào)參數(shù)類型不匹配的錯(cuò)誤,要把參數(shù)改為對(duì)象數(shù)組或者List對(duì)象:
@PostMapping(value = "/portal/core/appdata/install",consumes = "application/json;charset=UTF-8")
void install(@RequestBody Object[] data);
too many Body parameters問(wèn)題
問(wèn)題描述
feign的post請(qǐng)求只能有一個(gè)body feign的post方法中,只能使用一個(gè)@RequestBody或者不帶該注解,不能使用多個(gè)@RequestBody。
?否則會(huì)報(bào)錯(cuò)nested exception is java.lang.IllegalStateException: Method has too many Body parameters。
?
解決辦法
只保留一個(gè)@RequestBody注解
Read timed out問(wèn)題
問(wèn)題描述
feign調(diào)用超時(shí),會(huì)出現(xiàn)這個(gè)問(wèn)題。
一般來(lái)說(shuō)當(dāng)我們的業(yè)務(wù)需要處理的時(shí)間很大時(shí),會(huì)出現(xiàn)這個(gè)問(wèn)題。例如,上傳excel文件。
那這里我們可以進(jìn)行feign的超時(shí)時(shí)間設(shè)置。這里只針對(duì)指定的feign client
解決辦法
@FeignClient(name = "systemClient")
public interface SystemClient {
@RequestMapping(path = "/llsydn/importExcel", consumes = {"multipart/form-data"})
JsonResult importExcel(@RequestPart(name="file") MultipartFile file);
}
yml配置
feign:
httpclient:
enabled: true
client:
config:
default:
#默認(rèn)時(shí)間設(shè)置為10s
ConnectTimeOut: 10000
ReadTimeOut: 10000
#調(diào)用system微服務(wù),默認(rèn)時(shí)間設(shè)置為30s
systemClient:
ConnectTimeOut: 30000
ReadTimeOut: 30000
好了,以上就是我給公司研發(fā)人員解決問(wèn)題遇到的坑,與解決方案的分享。
可能內(nèi)容有點(diǎn)短,但都是干貨喔!!!
個(gè)人理解,可能也不夠全面,班門弄斧了。
如果覺(jué)得有收獲的,幫忙點(diǎn)贊、評(píng)論、收藏一下唄!!!

