Spring Boot参数校验实现自定义响应类优雅处理

😊 @ 作者: 一恍过去
💖 @ 主页: https://blog.csdn.net/zhuocailing3390
🎊 @ 社区: Java技术栈交流
🎉 @ 主题: Spring Boot参数校验实现自定义响应类优雅处理
⏱️ @ 创作时间: 2023年08月03日

在这里插入图片描述

目录

    • 目的:
      • 操作方式
      • @valid基本注解
      • 准备内容
      • 实现
        • 方法一:AOP、
        • 方式二:全局异常拦截(推荐)
      • 补充

目的:

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

操作方式

通过在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/19700.shtml

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

相关文章

【NLP概念源和流】 03-基于计数的嵌入,GloVe(第 3/20 部分)

接续上文 【NLP概念源和流】 02-稠密文档表示(第 2/20 部分)

AnimateDiff论文解读-基于Stable Diffusion文生图模型生成动画

文章目录 1. 摘要2. 引言3. 算法3.1 Preliminaries3.2. Personalized Animation3.3 Motion Modeling Module 4. 实验5.限制6. 结论 论文&#xff1a; 《AnimateDiff: Animate Your Personalized Text-to-Image Diffusion Models without Specific Tuning》 github: https://g…

vsto excel 可以异步写入值么

在 VSTO (Visual Studio Tools for Office) 中&#xff0c;Excel 可以使用异步方式写入值。异步编程允许您在后台线程中执行耗时的操作&#xff0c;而不会阻塞主线程&#xff0c;从而提高程序的响应性能。 从 .NET 4.5 开始&#xff0c;可以使用异步和 await 关键字来简化异步…

移动零 LeetCode热题100

题目 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 思路 遍历数组&#xff0c;用一个指针j记录上一次交换中的下标小的位置的下一个位…

【数据结构】——串,数组,矩阵的相关习题

目录 题型一&#xff08;二维数组的存储地址&#xff09;题型二&#xff08;串的模式匹配&#xff09;题型三&#xff08;串的基本操作&#xff09;题型四&#xff08;特殊矩阵的压缩存储&#xff09; 题型一&#xff08;二维数组的存储地址&#xff09; 1、二维数组A[m][n]采用…

数据分析 VS 数据可视化:决战时刻

数据分析和数据可视化是数据科学领域中两个重要的组成部分&#xff0c;很多人不明白两者之间的关系&#xff0c;会误认为是一个东西&#xff0c;其实不然。本文就带大家简单了解一下它们的区别与联系吧&#xff01; 数据分析是指通过收集、处理和解释数据来获取有关特定问题或…

【linux-网络】sslocal命令的安装使用

1.背景 需要ss转发&#xff0c;在linux中转发并登录。 2.操作流程&#xff1a; 1&#xff09;安装python 一般linux系统都自带python&#xff0c;2.7---如果要更高版本的自行安装 2&#xff09;使用pip安装ss pip install shadowsocks 3&#xff09;命令使用 sslocal -c …

无涯教程-Lua - 嵌套if语句函数

在Lua编程中&#xff0c;您可以在另一个if or else if语句中使用一个if or else if语句。 nested if statements - 语法 嵌套if 语句的语法如下- if( boolean_expression 1) then--[ Executes when the boolean expression 1 is true --]if(boolean_expression 2)then--[ Ex…

ConCurrentHashMap常见面试题

1. JDK1.7和JDK1.8中ConCurrentHashMap的实现有什么不同&#xff1f; JDK1.7中的实现可以认为是大数组套小数组&#xff0c;大数组是Segment数组&#xff0c;小数组是HashEntry数组&#xff0c;锁是锁在大数组的元素上&#xff08;Segment&#xff09;&#xff0c;力度比较大&…

【BASH】回顾与知识点梳理(一)

【BASH】回顾与知识点梳理 一 前言一. 认识与学习 BASH1.1 硬件、核心与 Shell1.2 为何要学文字接口的 shell&#xff1f;1.3 系统的合法 shell 与 /etc/shells 功能1.4 Bash shell 的功能1.5 查询指令是否为 Bash shell 的内建命令&#xff1a; type1.6 指令的下达与快速编辑按…

VS+QT+VTK treeView树型结构模型加载隐藏实例

程序示例精选 VSQTVTK treeView树型结构模型加载隐藏实例 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对<<VSQTVTK treeView树型结构模型加载隐藏实例>>编写代码&#xff0c;代码…

Chrome 75不支持保存成mhtml的解决方法

在Chrome 75之前&#xff0c;可以设置chrome://flags -> save as mhtml来保存网页为mhtml。 升级新版&#xff0c;发现无法另存为/保存网页为MHTML了。 在网上搜索无果后&#xff0c;只得从chromium项目的commits中查找&#xff0c;原来chrome搞了个"Chrome Flag Owner…

Android 创建 Gradle Task 自动打包并上传至蒲公英

前言 Android 项目日常开发过程中&#xff0c;经常需要打包给到非开发人员验收或调试&#xff0c;例如测试阶段&#xff0c;就要经常基于测试服务器地址&#xff0c;打包安装包&#xff0c;给到组内测试人员进行测试&#xff0c;并且 BUG 修复完成之后也需要再次打包给到测试人…

差分隐私 MP-SPDZ框架安装

ubuntu虚拟机安装MP-SPDZ框架 1.下载安装包到虚拟机内 https://github.com/data61/MP-SPDZ/releases 安装git 报错Waiting for cache lock: Could not get lock /var/lib/dpkg/lock-frontend. It is held by process 4402(unattended-upgr) 解决方案 #杀死进程 sudo k…

Android 仿京东头部滚动头像动态变化

UI出了一个新需求&#xff0c;仿京东头部滚动&#xff0c;头像需要动态变化&#xff0c;先来看下京东的是什么效果 我们知道什么效果以后&#xff0c;接下来就想想怎么实现吧&#xff0c;Android常规吸顶折叠布局是由CoordinatorLayoutAppBarLayoutCollapsingToolbarLayout组成…

JAVA 反编译工具

Releases deathmarine/Luyten GitHub 安装exe 打开拖入文件即可

Express接口

1.创建基本的服务器 // 导入express模块 const express require(express); const send require(send);// 创建express的 服务器实例 const app express()// 启动服务器 app.listen(80, () > {console.log(express server running at );})2.创建API路由接口 // 导入expr…

「网络编程」传输层协议_ TCP协议学习_及原理深入理解(二 - 完结)[万字详解]

「前言」文章内容大致是传输层协议&#xff0c;TCP协议讲解的第二篇&#xff0c;续上篇TCP。 「归属专栏」网络编程 「主页链接」个人主页 「笔者」枫叶先生(fy) 目录 二、TCP协议2.9 TCP连接管理机制2.9.1 三次握手2.9.2 四次挥手2.9.3 演示查看TIME_WAIT和CLOSE_WAIT状态2.9.…

MySQL 远程操作mysql

可以让别人在他们的电脑上操作我电脑上的数据库 create user admin identified with mysql_native_password by admin; //设置账号密码都为admingrant all on *.* to admin; //给admin账号授权 授权完成

使用elementplus实现文本框的粘贴复制

需求&#xff1a; 文本框仅用于显示展示数据并且用户可以进行复制&#xff0c;并不会进行修改和编辑&#xff0c; 注意点&#xff1a; 1.首先且文本为多行。所以不能使用普通的el-input&#xff0c;这种一行超出就会隐藏了&#xff0c;如果多行超出行数也会隐藏&#xff08;…