SpringBoot 3.x 必踩大坑:参数名丢失,全网最完整解决方案
【避坑指南】SpringBoot 3.x 必踩大坑参数名丢失全网最完整解决方案最近在项目从 SpringBoot 2.x 升级到SpringBoot 3.x JDK 17时遇到了一大堆莫名其妙的参数报错排查了很久才发现是 SpringBoot 3.x 编译机制改动导致的参数名丢失问题。本文把所有踩坑场景、报错日志、根因、解决方案一次性讲透看完直接解决你项目里 90% 的参数相关异常建议收藏一、前言SpringBoot 3.x 基于Spring Framework 6最低要求 JDK 17相比 2.x 版本有一个极易被忽略、但会导致大量接口报错的核心改动默认不再保留 Java 方法的参数名这会直接导致PathVariable接口报参数异常RequestParam接收不到参数Cacheable缓存 key 报 null 异常同样的代码2.x 完美运行3.x 直接报错二、最常见的 3 大报错场景场景 1PathVariable 路径参数报错报错日志java.lang.IllegalArgumentException: Name for argument of type [java.lang.Long] not specified, and parameter name information not found in class file either.错误代码GetMapping(/{id})publicResultUsergetById(PathVariableLongid){returnResult.success(userService.getById(id));}报错原因Spring 无法识别参数id对应路径中的{id}直接抛出参数未指定异常。场景 2Cacheable 缓存 key 报错报错日志java.lang.IllegalArgumentException: Null key returned for cache operation (maybe you are using named params on classes without debug info?) Builder[public com.demo.entity.User com.demo.service.impl.UserServiceImpl.getById(java.lang.Long)] caches[user] | key#id | keyGenerator错误代码Cacheable(valueuser,key#id)publicUsergetById(Longid){returnuserMapper.selectById(id);}报错原因Spring 无法解析 SpEL 表达式中的#id认为缓存 key 为 null直接抛出异常。场景 3RequestParam 请求参数报错报错日志Required request parameter id for method parameter type Long is not present错误代码GetMapping(/user)publicResultgetUser(RequestParamLongid){returnResult.success(userService.getById(id));}报错原因Spring 无法匹配请求参数与方法参数名提示参数缺失。三、核心根因SpringBoot 3.x 编译机制改动1. 底层原理SpringBoot 2.x默认开启参数名编译可直接读取方法参数名SpringBoot 3.x默认关闭参数名保留编译后的 class 文件中不包含方法参数名信息所有依赖参数名的注解都会因为找不到参数名而报错。2. 影响范围所有需要通过参数名绑定的注解全都会受影响PathVariableRequestParamRequestHeaderCacheable/CacheEvict/CachePutMyBatis 接口参数、SpEL 表达式四、分场景解决方案复制即用方案 1接口注解显式指定参数名最快修复1. PathVariable 修复GetMapping(/{id})publicResultUsergetById(PathVariable(id)Longid){log.info(查询用户: {},id);returnResult.success(userService.getById(id));}2. RequestParam 修复GetMapping(/user)publicResultgetUser(RequestParam(id)Longid){returnResult.success(userService.getById(id));}方案 2缓存注解 SpEL 表达式修复1. 使用参数下标推荐无需改配置#p0代表第一个参数#p1代表第二个参数以此类推Cacheable(valueuser,key#p0)publicUsergetById(Longid){returnuserMapper.selectById(id);}2. 使用参数索引写法Cacheable(valueuser,key#root.args[0])publicUsergetById(Longid){returnuserMapper.selectById(id);}五、永久根治方案一劳永逸不想每次都手动指定参数名直接在pom.xml中开启参数名编译完全回归 SpringBoot 2.x 写法。buildpluginsplugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-compiler-plugin/artifactIdconfiguration!-- 核心配置开启参数名保留SpringBoot 3.x 必加 --parameterstrue/parameterssource17/sourcetarget17/targetencodingUTF-8/encoding/configuration/plugin/plugins/build配置后效果PathVariable Long id✅ 正常使用Cacheable(key #id)✅ 正常解析RequestParam Long id✅ 正常接收所有参数相关报错全部消失六、避坑总结口诀方便大家记忆整理一句避坑口诀SpringBoot3升级忙参数丢失是家常 PathVariable加括号RequestParam写名上 缓存key用p0pom参数开启最稳当七、文末总结SpringBoot 3.x 最大的隐形坑默认不保留方法参数名所有参数绑定、SpEL 表达式都会受影响临时修复注解显式指定参数名永久修复pom.xml加parameterstrue/parameters项目升级 SpringBoot 3.x第一件事就是加这个编译配置原创声明本文为原创博客首发 CSDN禁止未经授权转载、搬运。如果本文对你有帮助欢迎点赞、收藏、关注后续持续分享 SpringBoot 3.x 实战避坑干货
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2592073.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!