Spring Boot 中的参数验证和自定义响应处理,使用 @Valid 注解

😊 @ 作者: 一恍过去
💖 @ 主页: https://blog.csdn.net/zhuocailing3390
🎊 @ 社区: Java技术栈交流
🎉 @ 主题: Spring Boot 中的参数验证和自定义响应处理,使用 @Valid 注解
⏱️ @ 创作时间: 2023年09月13日

在这里插入图片描述

目的:

对前端请求的数据进行格式、长度、是否为空等进行校验,可以防止脏数据对数据库的影响。

操作方式

通过在controller中加入@valid对请求参数进行校验
方式一、配合AOP实现
方式二、配合全局异常实现

@valid基本注解

常用主要注解如下:

注解作用参数
@Null验证是否为nullmessage=“返回信息”
@NotNull验证是否不为null, 无法查检长度为0的字符串message=“返回信息”
@NotBlank验证是否不为null, 并且不会过滤空格字符串message=“返回信息”
@NotEmpty验证String是否为null,或者对象是否emptymessage=“返回信息”
@Min参数必须大于等于该值value=数值,message=“返回信息”
@Max参数必须小于等于该值value=数值,message="返回信息
@Pattern参数必须满足正则表达式regexp=“正则”,message="返回信息
@Email参数必须为电子邮箱message=“返回信息”
@Valid对关联对象进行递归校验-
@Range验证数字的最大值与最小值min=, max=
@Size验证对象(Array,Collection,Map,String)长度最大值与最小值min=, max=
@Length验证String的长度最大值与最小值min=, max=

准备内容

pom:

<dependency><groupId>jakarta.validation</groupId><artifactId>jakarta.validation-api</artifactId>
</dependency>

0、响应类

public class ResponseObject {private Integer status;private Object data;private String message;public Integer getStatus() {return status;}public void setStatus(Integer status) {this.status = status;}public Object getData() {return data;}public void setData(Object data) {this.data = data;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public static ResponseObject failure(String message) {ResponseObject responseObject = new ResponseObject();responseObject.setStatus(500);responseObject.setData(false);responseObject.setMessage(message);return responseObject;}
}

1、实体类


public class User implements Serializable {/*** 用户名*/@NotEmpty(message = "不能为空")private String username;@Max(value = 20, message = "不能超过20")@Min(value = 10, message = "不能小于10")private Integer num;public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public Integer getNum() {return num;}public void setNum(Integer num) {this.num = num;}
}

2、Controller

@RestController
public class UserController {@ParamValid@GetMapping("/get")public ResponseObject getUser(@Valid User user, BindingResult bindingResult) {return ResponseObject.failure("");}@PostMapping("/post")public ResponseObject postUser(@Valid @RequestBody User user) {return ResponseObject.failure("");}
}

3、自定义注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface ParamValid {}

4、AOP类

@Component
@Aspect
public class ParameterValidAop {@Before("@annotation(paramValid)")public void paramValid(JoinPoint point, ParamValid paramValid) throws Exception {Object[] paramObj = point.getArgs();for (Object obj : paramObj) {if (obj instanceof BindingResult) {BindingResult result = (BindingResult) obj;if (result.hasErrors()) {List<ObjectError> allErrors = result.getAllErrors();//返回第一个错误String defaultMessage = allErrors.get(0).getDefaultMessage();throw new Exception(defaultMessage);}}}}
}

5、全局异常

 @RestControllerAdvice
@Slf4j
public class GlobalException {/*** 参数校验异常*/@ResponseStatus(HttpStatus.OK)@ExceptionHandler(MethodArgumentNotValidException.class)public ResponseObject handlerMethodArgumentNotValidException(MethodArgumentNotValidException e) {BindingResult bindingResult = e.getBindingResult();// 所有参数异常信息List<ObjectError> allErrors = bindingResult.getAllErrors();return ResponseObject.failure(allErrors.get(0).getDefaultMessage());}@ResponseStatus(HttpStatus.OK)@ExceptionHandler(BindException.class)public ResponseObject handlerBindException(BindException e) {BindingResult bindingResult = e.getBindingResult();// 所有参数异常信息List<ObjectError> allErrors = bindingResult.getAllErrors();return ResponseObject.failure(allErrors.get(0).getDefaultMessage());}
}

实现

方法一:AOP、

在controller中加入@Valid、 @ParamValid注解,以及BindingResult参数

@ParamValid@GetMapping("/get")public ResponseObject getUser(@Valid User user, BindingResult bindingResult) {return ResponseObject.failure("");}

通过postman访问conrtoller地址,写入的参数并且不满足规则,可以看到会抛出错误异常
在这里插入图片描述
可以看到在抛出的异常中,并是不自己定义的格式,如果想要返回自定义的响应实体,需要在全局异常中写一个自定义异常,并且获取在AOP中抛出的差异,是不是觉得有点麻烦,在用的AOP以后,还需要进行额外的代码操作,所以推荐第二中方式,直接使用全局异常进行拦截 ,并且返回自定义响应。

方式二:全局异常拦截(推荐)

controller如下:

@GetMapping("/get")public ResponseObject getUser(@Valid User user) {return ResponseObject.failure("");}@PostMapping("/post")public ResponseObject postUser(@Valid @RequestBody User user) {return ResponseObject.failure("");}

进行请求
在这里插入图片描述
可以看到控制台打印了错误信息,意思就是如果出现了不满足条件的参数请求,会自动抛出异常,那么我们就可以在自定义异常中进行捕获,代码看上面(5、全局异常)。
最后返回结果,就是自己打印的数据格式:
在这里插入图片描述

补充:

可以将所有错误提示一起返回

					List<ObjectError> allErrors = result.getAllErrors();//装载为集合List<ObjectError> allErrors = result.getAllErrors();List<String> lists = new ArrayList<>();for (ObjectError objectError : allErrors) {lists.add(objectError.getDefaultMessage());}

参考:@1nchaos https://www.cnblogs.com/1nchaos/p/11442559.html

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/77448.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【sgCreateAPI】自定义小工具:敏捷开发→自动化生成API接口脚本(接口代码生成工具)

<template><div :class"$options.name"><div class"sg-head">接口代码生成工具</div><div class"sg-container"><div class"sg-start "><div style"margin-bottom: 10px;">接口地…

如何进行函数的递归调用?

函数的递归调用是一种强大而常见的编程技巧&#xff0c;它允许函数在自身内部调用自己。递归在解决问题的分而治之策略中非常有用&#xff0c;可以将大问题分解为更小的、相同或类似的子问题&#xff0c;然后通过逐步解决这些子问题来解决原始问题。在本文中&#xff0c;我将详…

信息化发展39

IT 服务管理 1 、IT 服务管理是通过主动管理和流程的持续改进来确保IT 服务交付有效且高效的一组活动。 2 、IT 服务管理由若干不同的活动组成&#xff1a; 服务台、事件管理、问题管理、变更管理、配置管理、发布管理、服务级别管理、财务管理、容量管理、服务连续性管理和可…

做期权卖方一般会怎么选择合约?

我们知道期权有多种获利方式&#xff0c;其中靠时间能赚钱的是做期权卖方策略&#xff0c;虽然赚得慢&#xff0c;但可以稳稳地收入权利金&#xff0c;适合某些稳健风格的投资者&#xff0c;胜率对比买方也是高了很多&#xff0c;那么做期权卖方一般会怎么选择合约&#xff1f;…

Unity——JSON的读取

一、读取JSON 在实际中&#xff0c;读取JSON比保存JSON重要得多。因为存档、发送数据包往往可以采用其他序列化方法&#xff0c;但游戏的配置文件使用JSON格式比较常见。游戏的配置数据不属于动态数据&#xff0c;属于游戏资源&#xff0c;但很适合用JSON表示。 下面以一个简…

Mybatis---第二篇

系列文章目录 文章目录 系列文章目录一、#{}和${}的区别是什么?二、简述 Mybatis 的插件运行原理,如何编写一个插件一、#{}和${}的区别是什么? #{}是预编译处理、是占位符, KaTeX parse error: Expected EOF, got # at position 27: …接符。 Mybatis 在处理#̲{}时,会将…

Linux之Socket函数(详细篇)

本篇是基于Linux man手册的一些总结 socket作用&#xff1a; create an endpoint for communication 函数结构 c #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int socket(int domain, int type, int protocol); 描述 socket() …

LeetCode(力扣)45. 跳跃游戏 IIPython

LeetCode45. 跳跃游戏 II 题目链接代码 题目链接 https://leetcode.cn/problems/jump-game-ii/description/ 代码 class Solution:def jump(self, nums: List[int]) -> int:if len(nums) 1:return 0curdis 0nextdis 0step 0for i in range(len(nums)):nextdis max(…

华为云耀云服务器HECS安装Docker

先去购买服务器&#xff0c;这里就不多说了 1、进入自己买的服务器&#xff0c; 找到切换系统 2、选择centOs镜像 安装docker 卸载旧版本 较旧的 Docker 版本称为 docker 或 docker-engine 。如果已安装这些程序&#xff0c;请卸载它们以及相关的依赖项。 yum remove docker…

职业规划就问它!海量知识与智慧,AIGC助你冲破择业迷茫

数字化时代的兴起改变了我们的日常生活和职业工作方式。科技迅猛的发展&#xff0c;尤其是人工智能的崛起&#xff0c;将我们引入了一个崭新的智能化时代。在这个时代中&#xff0c;AI被认为是从"数字时代"向"数智时代"转变的关键元素&#xff0c;引领着这…

蛇形填数 rust解法

蛇形填数。 在nn方阵里填入1&#xff0c;2&#xff0c;…&#xff0c;nn&#xff0c;要求填成蛇形。例如&#xff0c;n&#xff1d;4时方阵为&#xff1a; 10 11 12 1 9 16 13 2 8 15 14 3 7 6 5 4 解法如下&#xff1a; use std::io;fn main() {let mut buf String::new();…

2023年Gartner新技术与AI成熟度曲线

1. Gartner 将生成式 AI 置于 2023 年新技术成熟度曲线的顶峰&#xff0c;新兴人工智能将对商业和社会产生深远影响 根据 Gartner, Inc. 2023 年新兴技术成熟度曲线&#xff0c;生成式人工智能 (AI) 处于成熟度曲线期望的顶峰&#xff0c;预计将在两到五年内实现转型效益。生成…

htaccess绕过上传实验

实验目的 利用上传htaccess文件解析漏洞绕过验证进行上传PHP脚本木马 实验工具 火狐&#xff1a;Mozilla Firefox&#xff0c;中文俗称“火狐”&#xff08;正式缩写为Fx或fx&#xff0c;非正式缩写为FF&#xff09;&#xff0c;是一个自由及开放源代码网页浏览器&#xff0…

Linux OpenGauss 数据库远程连接

目录 前言 1. Linux 安装 openGauss 2. Linux 安装cpolar 3. 创建openGauss主节点端口号公网地址 4. 远程连接openGauss 5. 固定连接TCP公网地址 6. 固定地址连接测试 前言 openGauss是一款开源关系型数据库管理系统&#xff0c;采用木兰宽松许可证v2发行。openGauss内…

【vue】下拉、上拉刷新

我这里就把主要的下拉刷新的写一下&#xff0c;上拉是一样的道理&#xff0c;就不写了 <div class"talk_top" ref"listWrapper" id"listWrapper"><div class"loadingpic" v-loading"loading"></div><d…

playwright自动化上传附件

需求 自动设置上传头像 过程 1. 首先保存本地一个文件&#xff0c;例如 aaa.php file_path files/aaa.png 2. 获取输入类型为 "file" 的按钮 file_input_element page.locator(input[typefile]) 3. 将本地保存的图片路径赋值 file_input_element.set_input_…

单例模式-饿汉模式、懒汉模式

单例模式&#xff0c;是设计模式的一种。 在计算机这个圈子中&#xff0c;大佬们针对一些典型的场景&#xff0c;给出了一些典型的解决方案。 目录 单例模式 饿汉模式 懒汉模式 线程安全 单例模式 单例模式又可以理解为是单个实例&#xff08;对象&#xff09; 在有些场…

深圳唯创知音电子将参加IOTE 2023第二十届国际物联网展•深圳站

​ 2023年9月20~22日&#xff0c;深圳唯创知音电子将在 深圳宝安国际会展中心&#xff08;9号馆9B1&#xff09;为您全面展示最新的芯片产品及应用方案&#xff0c;助力传感器行业的发展。 作为全球领先的芯片供应商之一&#xff0c;深圳唯创知音电子一直致力于为提供高质量、…

【Web】vue开发环境搭建教程(详细)

系列文章 C#底层库–记录日志帮助类 本文链接&#xff1a;https://blog.csdn.net/youcheng_ge/article/details/124187709 文章目录 系列文章前言一、安装准备1.1 node.js1.2 国内镜像站1.3 Vue脚手架1.4 element ui1.5 Visual Studio Code 二、安装步骤2.1 下载msi安装包2.2 …

骨传导耳机对人体有危险吗?会损害听力吗?

如果在使用骨传导耳机的时候控制好时间和音量&#xff0c;是不会对人体带来危险和造成伤害的。 下面跟大家解释一下为什么骨传导耳机对人体没有危害&#xff0c;最大的原因就是骨传导耳机不需要空气传导&#xff0c;而是通过颅骨传到听觉中枢&#xff0c;传输过程中几乎没有噪…