1. 程式人生 > >使用Feign傳送請求時,報405 Not Support Method

使用Feign傳送請求時,報405 Not Support Method

在使用Feign來呼叫Get請求介面時,如果方法的引數是一個物件,例如:

@FeignClient("microservice-provider-user")

public interface UserFeignClient {

@RequestMapping(value = "/user", method = RequestMethod.GET)

public User get0(User user);

}

那麼在除錯的時候你會一臉懵逼,因為報瞭如下錯誤:

feign.FeignException: status 405 reading UserFeignClient#get0(User); content:

{"timestamp":1482676142940,"status":405,"error":"Method Not Allowed""exception":"org.springframework.web.HttpRequestMethodNotSupportedException","message":"Request method 'POST' not supported","path":"/user"}

調整不用物件傳遞,一切OK,沒毛病,可仔細想想,你想寫一堆長長的引數嗎?用一個不知道里邊有什麼鬼的Map嗎?或者轉換為post?這似乎與REST風格不太搭,會浪費url資源,我們還需要在url定義上來區分Get或者Post。

我很好奇,我定義的Get請求怎麼就被轉成了Post,於是就開始逐行除錯,直到我發現了這個:

private synchronized OutputStream getOutputStream0() throws IOException {

try {

if(!this.doOutput) {

throw new ProtocolException("cannot write to a URLConnection if doOutput=false - call setDoOutput(true)");

else {

if(this.method.equals(

"GET")) {

this.method = "POST";

}

這段程式碼是在   HttpURLConnection 中發現的,jdk原生的http連線請求工具類,這個是Feign預設使用的連線工具實現類,但我記得我們的工程用的是apach的httpclient替換掉了原生的UrlConnection,我們用瞭如下配置:

feign:

httpclient:

enabled: true

同時在依賴中引入apache的httpclient

<dependency>

<groupId>org.apache.httpcomponents</groupId>

<artifactId>httpclient</artifactId>

<version>4.5.3</version>

</dependency>

<!-- 使用Apache HttpClient替換Feign原生httpclient --> 

<dependency>

<groupId>com.netflix.feign</groupId>

<artifactId>feign-httpclient</artifactId>

<version>${feign-httpclient}</version>

</dependency>

那我加上這個依賴後,請求通了,但是介面接收到物件裡邊屬性值是NULL;再看下邊的定義是不是少點什麼

@RequestMapping(value = "/user", method = RequestMethod.GET)

public User get0(User user);

對,少了一個註解:@RequestBody,既然使用物件傳遞引數,那傳入的引數會預設放在RequesBody中,所以在接收的地方需要使用@RequestBody來解析,最終就是如下定義:

@RequestMapping(value = "/user", method = RequestMethod.GET,consumer="application/json")

public User get0(@RequestBody User user);

注意:

                    若使用了@RequestBody註解,則只能傳送POST請求,即使你設定的為GET請求,也會轉為POST