問題1描述:
今天在A服務使用openfeign調用B服務的時候,發現經常會偶發性報錯。錯誤如下:
情況為偶發,很讓人頭疼。
兩個接口如下:
A服務接口:
delayReasonApi.test(student);
就是使用openfeign調用B服務的接口。
B服務接口:
原因分析:
因為A服務的接口是一個文件上傳的接口,所以前端請求頭中使用的是multipart/form-data 來請求的該接口。而B服務的接口是一個用json接口參數的接口,所以需要請求頭中的Content-Type為application/json。
如果在上面都沒有配置過的情況下,在B服務的接口參數使用@RequestBody注解來接受的時候,openfeign是會默認使用application/json 的content-type來進行請求的。代碼如下:
但是一般我們都會在項目中加上openfeign的配置文件,將目前的所有的header中的參數全部寫入openfeign的請求中,如下:
@Component
public class FeignConfiguration implements RequestInterceptor {@Overridepublic void apply(RequestTemplate template) {ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();if (attributes != null) {HttpServletRequest request = Objects.requireNonNull(attributes).getRequest();Enumeration<String> headerNames = request.getHeaderNames();if (headerNames != null) {while (headerNames.hasMoreElements()) {String name = headerNames.nextElement();String values = request.getHeader(name);template.header(name, values);}}}}
}
這樣就導致,我A服務接口使用的是multipart/form-data,而B服務接口需要的是application/json,而我的配置類會把A接口的multipart/form-data寫到請求頭中,這樣就會導致openfeign在請求的時候會有兩個content-Type,而且這兩個值的順序是不一定的,有的時候application/json在前面,有的時候multipart/form-data在前面:
我估計B服務在拿的時候只那集合中的第一個,但是我沒找源碼嘿嘿。當multipart/form-data在前面的時候,就會報上面的錯誤。
所以這個時候就有一個解決辦法:
把我們的配置類中的代碼進行修改,跳過content-type的賦值。
如此,openfeign就只會用默認的application/json進行請求了。
問題2描述:
延續上面的問題,當我修改了配置類之后,發現還是會有這樣的情況,后來發現是我們的微服務的項目中有兩個服務都寫了openfeign的配置類,而這兩個配置類都被引用在了A服務中。openfeign在調用接口的時候會先迭代所有的配置類,導致前面的情況又重演了一遍。
解決方法:
刪掉一個配置類。
問題3:
繼續上面的情況,如果B服務的接口也是個文件上傳接口,那么這個時候也是需要使用multipart/form-data的,那這個時候需要怎么做呢?openfeign是否會默認使用multipart/form-data呢?
B接口如下:
測試結果:
content-type為空,并且會報錯
解決辦法:
在B接口上加上 consumes = “multipart/form-data”
此時content-type就有值了。