起因
使用微服务架构SpringCloud的远程调用FeignClient各个微服务之前相互调用,其中使用get方法的时候报以下错误
java.lang.IllegalArgumentException: methodGETmustnothavearequestbody
原因
根本原因是:这个接口的请求方式是GET请求,接受的参数是一个对象(包含多个参数),而通过FeignClient调用的话GET请求方式是无法解析对象的,所以使用上述代码会报Caused by: java.lang.IllegalArgumentException: method GET must not have a request body错。
其实FeignClient是支持对象传递的,但是得是Map形式,而且不能为空,与spring在机制上不兼容,因此无法使用。而spring cloud在2.1.x版本中提供了@SpringQueryMap注解,可以传递对象参数,框架自动解析,只可惜啊,得是2.1.0以后的版本。对于上述第二种接口GET请求只传一个参数,通过FeignClient调用,同样也不支持。报错信息和第一种情况一模一样。
解决方案
方案1:POST请求 + 注解
将ServiceB接口的请求方式改为POST,同时接受的参数前面加上@RequestBody注解,改正后的代码如下:
/** * 设备查询 * @param equipmentQuery * @return */ @PostMapping("/equipment") PageResult<Equipment> page(@RequestBody EquipmentQuery equipmentQuery);
方案2:GET请求 + @SpringQueryMap注解
/** * 设备查询 * @param equipmentQuery * @return */ @PostMapping("/equipment") PageResult<Equipment> page(@SpringQueryMap EquipmentQuery equipmentQuery);
使用方案2的时候一定要注意Spring Cloud的版本,2.1.x以下的不支持哦,只有2.1.x以上版本才能解析参数。
方案3:GET请求 + @RequestParam("xxx")注解
/** * 设备详情 * * @param id * @return */ @GetMapping("/getById") R<EquipmentVO> info(@RequestParam("id") Integer id);
需要注意的是:
1、spring cloud项目使用FeignClient的时候GET请求方式无法解析对象参数
2、spring cloud项目使用FeignClient的时候GET请求有时候也无法解析单个参数值