引言

不知道大家是不是也有一种想法,就是喜欢用新的东西。比如:手机系统出现新版本就赶紧升级、软件出现新版本也会在第一时间进行升级。反正我是有这种想法,比较喜欢新的东西,因为新的东西会有更 cool 的特性,可以给人心理、生理上一种舒适感(生理舒适感???)。

背景介绍

公司不同项目使用的 SpringBoot 版本是不同的,最近在做的项目使用的是比较新的版本,2.x。该项目开发过程中,所有对外提供的服务,都会有一个接口层和接口实现层。为了让接口的职责更加的清晰明了,大部分信息都在接口层进行定义。比如:接口的请求映射路径,接口方法接收参数的方式@RequestBody 以及参数校验方式@Valid 等等。后来又去另一个项目组去开发,接到一个需要提供服务接口的任务,当时也没在意,觉得很简单,分分钟就可以完成,悲剧也就在此时此刻发生了。

接下来请大家先看看项目实例代码,在实例中会为大家重现错误,并提供解决方案以及分析出现该问题的原理是为什么。

项目实例

第一步:我们需要定义服务的接口

@RequestMapping("/persons")
public interface PersonApi {/*** add** @param person* @return*/@PostMapping("/")List<Person> add(@Valid @RequestBody Person person);/*** update** @param person* @return*/@PutMapping("/")List<Person> update(@Valid @RequestBody Person person);
}

第二步:有了服务接口,那么肯定会有服务接口的实现

@RestController
public class PersonController implements PersonApi{private static List<Person> personList = new ArrayList<>();static {personList.add(new Person(10001, "test1"));personList.add(new Person(10002, "test2"));personList.add(new Person(10003, "test3"));personList.add(new Person(10004, "test4"));personList.add(new Person(10005, "test5"));}@Overridepublic List<Person> add(Person person) {personList.add(person);return personList;}@Overridepublic List<Person> update(Person person) {personList.removeIf(p -> Objects.equals(p.getId(), person.getId()));personList.add(person);return personList;}
}

第三步:服务接口编写完成,就需要自己调用接口进行测试,接下来就进行接口测试

可以看到接口可以正常调用,说明接口上使用@RequestBody 起了作用。当然,本文到此还没有结束,好戏还在后面

第五步:开始展示真正的本领了,修改 SpringBoot 的版本号,将版本号修改为 1.5.8.RELEASE

第六步:再次接口调用

可以很神奇的看到,接口请求的参数并没有和我们的接口参数对象进行绑定,也就是我们的@RequestBody 注解不生效了。此时的我整个人都不好了,上一个项目写的好好的接口,到这里就不行了?难道是水土不服?于是打开了另一个项目,一个字母一个字母进行对照,生怕错误了什么,最终还是以我失败宣告结束。

尝试方法

当时是不想看源码的,因为看源码好累,于是我就在实现方法上也加上了同样的注解,准备尝试一下。

@Override
public List<Person> add(@RequestBody Person person) {personList.add(person);return personList;
}

不抱希望的尝试请求接口

当返回结果出现在我眼前的时候,只有“我靠”两个字能形容我的心情。突然有一种山重水复疑无路,柳暗花明又一村的感觉,整个世界又变的美好了。

虽然问题得到了完美解决,但是内心深处还是想了解下到底是为什么?只有弄清原理,下次在遇到此问题的时候,我们才可能迎刃而解,不费吹灰之力。接下来就为大家揭开这层神秘的面纱!

疑惑解答

SpringBooot1.5.8.RELEASE 源码分析

打开 RequestMappingHandlerAdapter#invokeHandlerMethod,找到如下代码

modelFactory.initModel(webRequest, mavContainer, invocableMethod);

一直到 MethodParameter#getParameterAnnotations

如上代码获取当前方法参数的注解信息,最终返回,重点:此处获取的是实现方法上的注解,并不会获取接口方法上的注解,所以必须在实现方法上加上注解。

SpringBooot2.2.0.RELEASE 源码分析

跟着上面的思路找到获取参数注解的方法

可以很清楚的看到升级后的 SpringBoot 的 HandlerMethodParameter 中重写了获取参数注解的方法,重写方法中调用了父类获取参数注解的方法,并且在自己的实现中又去获取了接口上的注解,然后进行组合。因此升级后的项目中可以在接口上定义注解,同样也可以在实现方法上定义注解。

此次的分享到此已经结束了,后续还会继续为大家带来精彩对决的吐血经历,让撸友多点发质,多点开心。

参考文献

  • 搭上 SpringBoot 请求处理源码分析专车

  • 搭上 SpringBoot 参数解析返回值处理源码分析专车

原创 | SpringBoot版本竟然引发这种问题,让我吐血三升!相关推荐

  1. Springboot版本+ Spring Framework版本 + jdk版本 + Maven版本

    Springboot版本+ Spring Framework版本 + jdk版本 + Maven版本的对应关系 Spring boot 版本 Spring Framework jdk 版本 maven ...

  2. [导入]Visual Studio 2005 Web Deployment Projects版本不同引发的问题

    Visual Studio 2005 Web Deployment Projects版本不同引发的问题 文章来源:http://blog.csdn.net/net_lover/archive/2006 ...

  3. SpringBoot版本:1.5.12.RELEASE 文件大小限制异常拦截网关zuul报错

    SpringBoot版本:1.5.12.RELEASE SpringCloud版本:1.4.3.RELEASE 文件上传异常处理代码: @Order(LOWEST_PRECEDENCE)//指定该实体 ...

  4. springboot版本兼容

    springboot版本兼容 一.Spring Boot 版本支持 Spring Boot Spring Framework Java Maven Gradle 1.2.0之前版本   6 3.0+ ...

  5. 通过官方查看springCloud,springBoot版本对应关系

    文章目录 1 官方文档查看 2 更优的查看方式 1 官方文档查看 在官网的Spring Cloud版本Hoxton SR7的Reference Doc中的内容如下,指定支持的boot版本为2.3.2. ...

  6. springboot版本的微信授权

    以前项目都是ssm版本的,最近从网上找了一些资料,修改了一版springboot版本的微信授权 代码: <!--微信授权--> <dependency><groupId& ...

  7. HC物业系统-springboot版本本地环境部署启动

    1.更新代码 后端代码 : git https://gitee.com/wuxw7/MicroCommunity.git 前端代码:git https://gitee.com/java110/Wech ...

  8. spring-boot版本报红/出错的解决方法

    关于spring-boot版本报红/出错的解决方法 环境交代 开发工具: idea 语言:java 在maven项目中使用Springboot,依赖spring-boot-starter-parent ...

  9. Elasticsearch和springboot版本对应

    Elasticsearch和springboot版本不兼容 springboot 2.1.6 对应 Elasticsearch 6.3.2 springboot 2.2.5 对应 Elasticsea ...

最新文章

  1. 桌面程序调用Web Service应用实例
  2. webpack初探——js打包
  3. Web开发:HTML5、CSS、JavaScript必备教程
  4. 全球及中国抗甲状腺药物行业应用现状调研及未来产销需求预测报告2021-2027年
  5. 推荐算法炼丹笔记:CTR点击率预估系列入门手册
  6. php图片旋转显示不出来的,php – 我服务的图像不正确,它们都显示为旋转90度
  7. golang文件夹位置判断
  8. 我喜欢用计算机400字,我的电脑400字作文
  9. Windows下打印服务器的管理(二)
  10. 旅游展示网站-前端网页设计技术完整精美源码HTML+CSS+JS
  11. php中的字典数据类型,python中字典数据类型常用操作
  12. 基于 AUTOSAR 的电动汽车中央控制单元 CAN 通信软件开发
  13. 计算机网络拓扑结构功能是,计算机网络拓扑结构
  14. 如何添加PR视频特效?
  15. 实现加入购物车的功能
  16. 电脑屏幕为什么没有手机屏幕清晰?
  17. java 动态修改配置文件_Java 项目中一种简单的动态修改配置即时生效的方式 WatchService...
  18. mercury路由器重置后服务器无响应,路由器复位不了,重置后进不去如何解决
  19. 复现《nature communications》图表(一):一模一样的Figure1
  20. C++ L1-034. 点赞

热门文章

  1. Ubuntu中Python无法显示图片
  2. SMART PLC和V90伺服实现外部脉冲位置控制
  3. 基于微信小程序的自习室预约系统设计与实现-计算机毕业设计源码+LW文档
  4. 搭建ftp文件服务器
  5. 【Python】【C语言】P3353 在你窗外闪耀的星星
  6. DFS基础-----刷题合集--1(全排列,八皇后,迷宫),让你明白DFS的基础用法
  7. 基于机器视觉的机器人智能制造实践应用研究
  8. springboot下载resource下的静态资源,下载excel文件损坏
  9. 游戏运营的十二大组成
  10. 2021年广州市学历入户全流程(持续更新)