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,一经查实,立即删除!

相关文章

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…

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

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

无涯教程-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…

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;…

用blender做一层石墨烯

文章目录 1 创建正六边形2 复制正六边形3 阵列4 球棍模型 1 创建正六边形 ShiftA->网格->圆环->左下角出现添加圆环菜单&#xff0c;将顶点设为6&#xff0c;得到一个正六边形。按下tab键进入编辑模式->快捷键F填充&#xff0c;得到下图 2 复制正六边形 首先将轴…

Django的FBV和CBV

Django的FBV和CBV 基于django开发项目时&#xff0c;对于视图可以使用 FBV 和 CBV 两种模式编写。 FBV&#xff0c;function base views&#xff0c;其实就是编写函数来处理业务请求。 from django.contrib import admin from django.urls import path from app01 import view…

Redis主从复制、哨兵机制、集群分片

一.主从复制 1.概述 主从复制&#xff0c;是指将一台Redis服务器的数据&#xff0c;复制到其他的Redis服务器。前者称为主节点(master)&#xff0c;后者称为从节点(slave)。 数据的复制是单向的&#xff0c;只能由主节点到从节点默认情况下&#xff0c;每台Redis服务器都是主节…

机器学习深度学习——权重衰减

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位即将上大四&#xff0c;正专攻机器学习的保研er &#x1f30c;上期文章&#xff1a;机器学习&&深度学习——模型选择、欠拟合和过拟合 &#x1f4da;订阅专栏&#xff1a;机器学习&&深度学习 希望文章对你…

Vue2.0基础

1、概述 Vue(读音/vju/&#xff0c;类似于view)是一套用于构建用户界面的渐进式框架&#xff0c;发布于2014年2月。与其它大型框架不同的是&#xff0c;Vue被设计为可以自底向上逐层应用。Vue 的核心库只关注视图层&#xff08;也就是可以理解为HTMLCSSJS&#xff09;&#xff…