【Java异常】Caused by: java.lang.IllegalArgumentException: method GET must not have a request body

本文目录

一、背景描述

二、出错的代码

三、出错原因

四、解决方案

4.1 方案1:POST请求 + 注解

4.2 方案2:GET请求 + @SpringQueryMap注解

4.3 方案3:GET请求 + @RequestParam("xxx")注解


一、背景描述

公司做的智能家居系统改为微服务框架,各个微服务之前相互调用。

今天在做测试的时候后台系统报了一个Caused by: java.lang.IllegalArgumentException: method GET must not have a request body错误,然后检查了请求链路从前到后一路上全部是GET请求方式。通过Debug调试,页面请求可以打进serviceA,参数也可以携带进方法内,一步一步向下走,发现通过FeignClient调用serviceB的时候,报出这个异常。

二、出错的代码

以下两个接口都是ServiceA通过FiegnClient调用ServiceB的接口(通过FeignClient调用的接口)

第一种ServiceB接口的代码

/**
 * 根据主机sn查询远程运维记录
 * @param distanceMaintainRecordQuery
 * @return
*/
@GetMapping("/client/v1.0/distanceMaintain/pageMaintain")
PageResult<DistanceMaintainRecordBO> pageMaintain(DistanceMaintainRecordQuery distanceMaintainRecordQuery);

第二种ServiceB接口的代码

/**
* 查询屏保详情
*
* @param id
* @return
*/
@GetMapping("/client/v1.0/screenSaver/info")
CommResponse<ScreenSaverBO> info(Integer id);

三、出错原因

报出这个异常的原因是:这个接口的请求方式是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调用,同样也不支持。报错信息和第一种情况一模一样。

四、解决方案

4.1 方案1:POST请求 + 注解

将ServiceB接口的请求方式改为POST,同时接受的参数前面加上@RequestBody注解,改正后的代码如下:

/**
 * 根据主机sn查询远程运维记录
 * @param distanceMaintainRecordQuery
 * @return
*/
@PostMapping("/client/v1.0/distanceMaintain/pageMaintain")
PageResult<DistanceMaintainRecordBO> pageMaintain(@RequestBody DistanceMaintainRecordQuery distanceMaintainRecordQuery);

4.2 方案2:GET请求 + @SpringQueryMap注解

/**
 * 根据主机sn查询远程运维记录
 * @param distanceMaintainRecordQuery
 * @return
 */
@GetMapping("/client/v1.0/distanceMaintain/pageMaintain")
PageResult<DistanceMaintainRecordBO> pageMaintain(@SpringQueryMap DistanceMaintainRecordQuery distanceMaintainRecordQuery);

使用方案2的时候一定要注意Spring Cloud的版本,2.1.x以下的不支持哦,只有2.1.x以上版本才能解析参数。

4.3 方案3:GET请求 + @RequestParam("xxx")注解

/**
* 查询屏保详情
*
* @param id
* @return
*/
@GetMapping("/client/v1.0/screenSaver/info")
CommResponse<ScreenSaverBO> info(@RequestParam("id") Integer id);

需要注意的是:

1、spring cloud项目使用FeignClient的时候GET请求方式无法解析对象参数

2、spring cloud项目使用FeignClient的时候GET请求有时候也无法解析单个参数值

拓展:如何使用Feign构造多参数的请求:http://www.itmuch.com/spring-cloud-sum/feign-multiple-params-2/

原文地址:https://www.cnblogs.com/no8g/p/13415475.html