本節我們來探討如何使用Feign構造多參數的請求。筆者以GET以及POST方法的請求為例進行講解,其他方法(例如DELETE、PUT等)的請求原理相通,讀者可自行研究。
GET請求多參數的URL
假設我們請求的URL包含多個參數,例如http://microservice-provider-user/get?id=1&username=張三,要如何構造呢?
我們知道,Spring Cloud為Feign添加了Spring MVC的註解支持,那麼我們不妨按照Spring MVC的寫法嘗試一下:
@FeignClient("microservice-provider-user")public interface UserFeignClient { @RequestMapping(value = "/get", 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":"/get"}
由異常可知,儘管我們指定了GET方法,Feign依然會使用POST方法發送請求。
正確寫法如下:
(1) 方法一
@FeignClient(name = "microservice-provider-user")public interface UserFeignClient { @RequestMapping(value = "/get", method = RequestMethod.GET) public User get1(@RequestParam("id") Long id, @RequestParam("username") String username);}這是最為直觀的方式,URL有幾個參數,Feign接口中的方法就有幾個參數。使用@RequestParam註解指定請求的參數是什麼。
(2) 方法二
多參數的URL也可使用Map來構建。當目標URL參數非常多的時候,可使用這種方式簡化Feign接口的編寫。
@FeignClient(name = "microservice-provider-user")public interface UserFeignClient { @RequestMapping(value = "/get", method = RequestMethod.GET) public User get2(@RequestParam Map<String, Object> map);}在調用時,可使用類似以下的代碼。
public User get(String username, String password) { HashMap<String, Object> map = Maps.newHashMap(); map.put("id", "1"); map.put("username", "張三"); return this.userFeignClient.get2(map);} POST請求包含多個參數
下面我們來討論如何使用Feign構造包含多個參數的POST請求。假設服務提供者的Controller是這樣編寫的:
@RestControllerpublic class UserController { @PostMapping("/post") public User post(@RequestBody User user) { ... }}我們要如何使用Feign去請求呢?答案非常簡單,示例:
@FeignClient(name = "microservice-provider-user")public interface UserFeignClient { @RequestMapping(value = "/post", method = RequestMethod.POST) public User post(@RequestBody User user);} TIPS
(1) 本節相關代碼,詳見本書配套代碼中的microservice-provider-user-multiple-params項目和microservice-consumer-movie-feign-multiple-params項目。
(2) 除本節講解的方式外,我們也可編寫自己的編碼器來構造多參數的請求,但這種方式編碼成本較高,代碼可重用性較低。故此,本書不再贅述。
拓展閱讀
(1) 希望Feign能夠支持參數請求使用POJO的Issue:https://github.com/spring-cloud/spring-cloud-netflix/issues/1253
(2) 建議使用Feign原生的註解的Issue:https://github.com/spring-cloud/spring-cloud-netflix/issues/659
(3) 建議增強Feign的功能:https://github.com/spring-cloud/spring-cloud-netflix/issues/1360
(4) 建議支持可選的Request Body(目前Feign當POST一個null時,會報異常):https://github.com/spring-cloud/spring-cloud-netflix/issues/1047
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持武林網。