springboot如何处理:参数校验、统一异常、统一响应
文章来源:http://suo.nz/1KaLX0
前言
Controller 层参数接收
统一状态码
统一校验
统一响应
统一异常
前言
本篇主要要介绍的就是 controller 层的处理,一个完整的后端请求由 4 部分组成:
接口地址(也就是 URL 地址)
请求方式(一般就是 get、set,当然还有 put、delete)
请求数据(request,有 head 跟 body)
响应数据(response)
本篇将解决以下 3 个问题:
当接收到请求时,如何优雅的校验参数 返回响应数据该如何统一的进行处理 接收到请求,处理业务逻辑时抛出了异常又该如何处理
Controller 层参数接收(太基础了,可以跳过)
RestController:之前解释过,@RestController=@Controller+ResponseBody。
加上这个注解,springboot 就会吧这个类当成 controller 进行处理,然后把所有返回的参数放到 ResponseBody 中。
@RequestMapping:请求的前缀,也就是所有该 Controller 下的请求都需要加上 /product/product-info 的前缀。
@GetMapping("/findById"):标志这是一个 get 请求,并且需要通过 /findById 地址才可以访问到。
@PostMapping("/page"):同理,表示是个 post 请求。
统一状态码
| 返回格式
为了跟前端妹妹打好关系,我们通常需要对后端返回的数据进行包装一下,增加一下状态码,状态信息,这样前端妹妹接收到数据就可以根据不同的状态码,判断响应数据状态,是否成功是否异常进行不同的显示。
当然这让你拥有了更多跟前端妹妹的交流机会,假设我们约定了 1000 就是成功的意思。
| 封装 ResultVo
这些状态码肯定都是要预先编好的,怎么编呢?写个常量 1000?还是直接写死 1000?
要这么写就真的书白读的了,写状态码当然是用枚举拉:
最后返回就会是上面带了状态码的数据了。
统一校验
| 原始做法
这 if 写的人都傻了,能忍吗?肯定不能忍啊。
| @Validated 参数校验
运行看看,如果参数不对会发生什么?
我们故意传一个价格为 -1 的参数过去:
大功告成了吗?虽然成功校验了参数,也返回了异常,并且带上"商品价格不允许为负数"的信息。
但是你要是这样返回给前端,前端妹妹就提刀过来了,当年约定好的状态码,你个负心人说忘就忘?
用户体验小于等于 0 啊!所以我们要进行优化一下,每次出现异常的时候,自动把状态码写好,不负妹妹之约!
| 优化异常处理
玩你个头啊完美,这么呆瓜的操作 springboot 不知道吗?spring mvc 当然知道拉,所以给我们提供了一个 @RestControllerAdvice 来增强所有 @RestController,然后使用 @ExceptionHandler 注解,就可以拦截到对应的异常。
这里我们就拦截 BindException.class 就好了。最后在返回之前,我们对异常信息进行包装一下,包装成 ResultVo,当然要跟上 ResultCode.VALIDATE_ERROR 的异常状态码。
统一响应
| 统一包装响应
开发小哥肯定不乐意了,谁有空天天写 new ResultVo(data) 啊,我就想返回一个实体!怎么实现我不管!
①@RestControllerAdvice(basePackages = {"com.bugpool.leilema"}) 自动扫描了所有指定包下的 controller,在 Response 时进行统一处理。
②重写 supports 方法,也就是说,当返回类型已经是 ResultVo 了,那就不需要封装了,当不等与 ResultVo 时才进行调用 beforeBodyWrite 方法,跟过滤器的效果是一样的。
③最后重写我们的封装方法 beforeBodyWrite,注意除了 String 的返回值有点特殊,无法直接封装成 json,我们需要进行特殊处理,其他的直接 new ResultVo(data); 就 ok 了。
| NOT 统一响应
不开启统一响应原因:开发小哥是开心了,可是其他系统就不开心了。举个例子:我们项目中集成了一个健康检测的功能,也就是这货。
公司部署了一套校验所有系统存活状态的工具,这工具就定时发送 get 请求给我们系统:
“兄弟,你死了吗?”
“我没死,滚”
“兄弟,你死了吗?”
“我没死,滚”
是的,web 项目的本质就是复读机。一旦发送的请求没响应,就会给负责人发信息(企业微信或者短信之类的),你的系统死啦!赶紧回来排查 bug 吧!
人家要的返回只要一个 success,人家定的标准不可能因为你一个系统改。俗话说的好,如果你改变不了环境,那你就只能我****
新增不进行封装注解:因为百分之 99 的请求还是需要包装的,只有个别不需要,写在包装的过滤器吧?又不是很好维护,那就加个注解好了。所有不需要包装的就加上这个注解。
统一异常
每个系统都会有自己的业务异常,比如库存不能小于 0 子类的,这种异常并非程序异常,而是业务操作引发的异常,我们也需要进行规范的编排业务异常状态码,并且写一个专门处理的异常类,最后通过刚刚学习过的异常拦截统一进行处理,以及打日志。
后端小哥开发有效率,前端妹妹获取到 2003 状态码,调用对应警告弹窗,title 写上订单不存在,body 详细信息记载"订单号不存在:1998"。同时日志还自动打上去了!666!老哥们三连点个赞!
__EOF__

本文链接:https://www.cnblogs.com/dusucyy/p/16436294.html
关于博主:编程小萌新一名,希望从今天开始慢慢提高,一步步走向技术的高峰!
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?