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

本文涉及的产品
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
简介: 【Java异常】Caused by: java.lang.IllegalArgumentException: method GET must not have a request body

一、背景描述

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

今天在做测试的时候后台系统报了一个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构造多参数的请求:如何使用Feign构造多参数的请求 | 周立的博客 - 关注Spring Cloud、Docker


目录
打赏
0
0
1
1
17
分享
相关文章
|
3月前
|
在 Java 中捕获和处理自定义异常的代码示例
本文提供了一个 Java 代码示例,展示了如何捕获和处理自定义异常。通过创建自定义异常类并使用 try-catch 语句,可以更灵活地处理程序中的错误情况。
121 1
如何避免 Java 中的 TimeoutException 异常
在Java中,`TimeoutException`通常发生在执行操作超过预设时间时。要避免此异常,可以优化代码逻辑,减少不必要的等待;合理设置超时时间,确保其足够完成正常操作;使用异步处理或线程池管理任务,提高程序响应性。
212 13
|
3月前
|
在 Java 中,如何自定义`NumberFormatException`异常
在Java中,自定义`NumberFormatException`异常可以通过继承`IllegalArgumentException`类并重写其构造方法来实现。自定义异常类可以添加额外的错误信息或行为,以便更精确地处理特定的数字格式转换错误。
66 1
Java社招面试题:一个线程运行时发生异常会怎样?
大家好,我是小米。今天分享一个经典的 Java 面试题:线程运行时发生异常,程序会怎样处理?此问题考察 Java 线程和异常处理机制的理解。线程发生异常,默认会导致线程终止,但可以通过 try-catch 捕获并处理,避免影响其他线程。未捕获的异常可通过 Thread.UncaughtExceptionHandler 处理。线程池中的异常会被自动处理,不影响任务执行。希望这篇文章能帮助你深入理解 Java 线程异常处理机制,为面试做好准备。如果你觉得有帮助,欢迎收藏、转发!
73 14
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
java语言后台管理若依框架-登录提示404-接口异常-系统接口404异常如何处理-登录验证码不显示prod-api/captchaImage 404 (Not Found) 如何处理-解决方案优雅草卓伊凡
59 5
怎样避免 Java 中的 NoSuchFieldError 异常
在Java中避免NoSuchFieldError异常的关键在于确保类路径下没有不同版本的类文件冲突,避免反射时使用不存在的字段,以及确保所有依赖库版本兼容。编译和运行时使用的类版本应保持一致。
132 8
如何避免在 Java 中出现 NoSuchElementException 异常
在Java中,`NoSuchElementException`通常发生在使用迭代器、枚举或流等遍历集合时,尝试访问不存在的元素。为了避免该异常,可以在访问前检查是否有下一个元素(如使用`hasNext()`方法),或者使用`Optional`类处理可能为空的情况。正确管理集合边界和条件判断是关键。
139 6
|
2天前
|
【Java并发】【线程池】带你从0-1入门线程池
欢迎来到我的技术博客!我是一名热爱编程的开发者,梦想是编写高端CRUD应用。2025年我正在沉淀中,博客更新速度加快,期待与你一起成长。 线程池是一种复用线程资源的机制,通过预先创建一定数量的线程并管理其生命周期,避免频繁创建/销毁线程带来的性能开销。它解决了线程创建成本高、资源耗尽风险、响应速度慢和任务执行缺乏管理等问题。
90 60
【Java并发】【线程池】带你从0-1入门线程池
Java 面试必问!线程构造方法和静态块的执行线程到底是谁?
大家好,我是小米。今天聊聊Java多线程面试题:线程类的构造方法和静态块是由哪个线程调用的?构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节有助于掌握Java多线程机制。下期再见! 简介: 本文通过一个常见的Java多线程面试题,详细讲解了线程类的构造方法和静态块是由哪个线程调用的。构造方法由创建线程实例的主线程调用,静态块在类加载时由主线程调用。理解这些细节对掌握Java多线程编程至关重要。
48 13

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等