SpringBoot参数校验详解
前言
在web开发时,对于请求参数,一般上都需要进行参数合法性校验的,原先的写法时一个个字段一个个去判断,这种方式太不通用了,Hibernate Validator 是 Bean Validation 规范的参考实现,用于在 Java 应用中进行对象的校验。以下是如何在 Spring Boot 项目中安装和使用 Hibernate Validator 的详细步骤。
一、Hibernate Validator参数校验依赖的安装
SpringBoot 2.3以前版本
<!-- Spring Boot Starter Web 包含了 Spring MVC 和 Bean Validation 等常用依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
Springboot从2.3以后,spring-boot-starter-web中不再引入hibernate-validator,需要手动引入。
<!-- Spring Boot Starter Web 包含了 Spring MVC 和 Bean Validation 等常用依赖 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Hibernate Validator 是 Bean Validation 的默认实现 --><dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId></dependency>
二、SpringBoot参数校验异常返回结果类封装
在使用 Spring Boot 进行参数校验时,如果参数不符合要求,会抛出校验异常。为了更好地处理这些异常并返回统一的错误格式,可以通过以下方式进行封装:
1. 使用 @ControllerAdvice
全局异常处理
创建一个全局异常处理类,捕获 MethodArgumentNotValidException
和 ConstraintViolationException
,并将其转换为统一的响应格式。
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.ResponseStatus;import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;@ControllerAdvice
public class GlobalExceptionHandler {// 处理 @Valid 校验异常@ExceptionHandler(MethodArgumentNotValidException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)@ResponseBodypublic Map<String, Object> handleValidationException(MethodArgumentNotValidException ex) {Map<String, Object> errors = new HashMap<>();errors.put("status", HttpStatus.BAD_REQUEST.value());errors.put("message", "Validation failed");Map<String, String> fieldErrors = new HashMap<>();for (FieldError error : ex.getBindingResult().getFieldErrors()) {fieldErrors.put(error.getField(), error.getDefaultMessage());}errors.put("errors", fieldErrors);return errors;}// 处理 @Validated 校验异常@ExceptionHandler(ConstraintViolationException.class)@ResponseStatus(HttpStatus.BAD_REQUEST)@ResponseBodypublic Map<String, Object> handleConstraintViolationException(ConstraintViolationException ex) {Map<String, Object> errors = new HashMap<>();errors.put("status", HttpStatus.BAD_REQUEST.value());errors.put("message", "Validation failed");Map<String, String> fieldErrors = new HashMap<>();Set<ConstraintViolation<?>> violations = ex.getConstraintViolations();for (ConstraintViolation<?> violation : violations) {fieldErrors.put(violation.getPropertyPath().toString(), violation.getMessage());}errors.put("errors", fieldErrors);return errors;}
}
2. 自定义返回结果格式
在返回结果中包含自定义的状态码、错误信息和字段错误列表。
例如:
{"status": 400,"message": "Validation failed","errors": {"fieldName1": "Error message 1","fieldName2": "Error message 2"}
}
3. 参数校验示例
控制器中可以使用 @Valid
或 @Validated
注解进行参数校验:
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;import javax.validation.Valid;@RestController
public class UserController {@PostMapping("/users")public ResponseEntity<String> createUser(@Valid @RequestBody UserRequest userRequest) {// 业务逻辑return ResponseEntity.ok("User created successfully");}
}
4. 校验注解
在请求对象中使用 JSR-303/JSR-380 提供的校验注解,例如 @NotNull
, @Size
, @Email
等。
import javax.validation.constraints.Email;
import javax.validation.constraints.NotBlank;
import javax.validation.constraints.Size;public class UserRequest {@NotBlank(message = "Username is mandatory")@Size(min = 3, max = 20, message = "Username must be between 3 and 20 characters")private String username;@NotBlank(message = "Email is mandatory")@Email(message = "Email should be valid")private String email;// getters and setters
}
通过以上方法,可以将参数校验异常统一封装成一个标准格式的响应结果,便于前端处理。
三、@Valid 和 @Validated之间的区别
@Valid
和 @Validated
是 Spring 框架中用于进行参数验证的两个注解,尽管它们的作用相似,但在使用场景和功能上有一些区别:
1. @Valid
- 作用:
@Valid
是 JSR-303/JSR-380 标准中的注解,用于在 Bean Validation 中对对象进行校验。它可以用在方法参数、返回值、或者类字段上。 - 适用范围:
- 对单个对象进行校验。
- 当用在集合类(如
List
、Set
)或者数组时,它会对集合中的每个元素进行校验。
- 典型用法:
@PostMapping("/user") public ResponseEntity<String> createUser(@Valid @RequestBody User user) {// 如果 user 对象不符合校验规则,会抛出 MethodArgumentNotValidExceptionreturn ResponseEntity.ok("User created"); }
2. @Validated
- 作用:
@Validated
是 Spring 提供的一个注解,扩展了@Valid
的功能。除了能够进行标准的 Bean Validation 校验外,它还支持分组校验(Group Validation)。 - 适用范围:
- 可以用来对不同的校验场景使用不同的校验规则(通过分组)。
- 主要在 Spring 的
@Service
、@Controller
等类中用于方法级别的校验。
- 典型用法:
@PostMapping("/user") public ResponseEntity<String> createUser(@Validated(OnCreate.class) @RequestBody User user) {// 如果 user 对象不符合 OnCreate 分组的校验规则,会抛出 MethodArgumentNotValidExceptionreturn ResponseEntity.ok("User created"); }
主要区别:
-
标准 vs. 扩展:
@Valid
是标准的 Java Bean Validation 注解。@Validated
是 Spring 提供的扩展注解,支持更多功能。
-
分组校验:
@Valid
不支持分组校验,只能进行默认的校验。@Validated
支持分组校验,允许根据不同的操作或场景应用不同的校验逻辑。
-
使用场景:
- 如果只需要基本的校验,使用
@Valid
即可。 - 如果需要在不同的场景下应用不同的校验逻辑,使用
@Validated
并结合分组校验。
- 如果只需要基本的校验,使用
希望这些信息能帮你更好地理解这两个注解的区别。
四、常用的校验参数详解
结合 Hibernate Validator 实现。通过在实体类字段或方法参数上使用各种注解,可以轻松进行参数校验。
以下是 Spring Boot 中常用的参数校验注解及其用法详解:
1. 基本校验注解
-
@NotNull:字段不能为
null
,但可以为空字符串。@NotNull(message = "Name cannot be null") private String name;
-
@NotEmpty:字段不能为
null
,也不能为空字符串或空集合。@NotEmpty(message = "List cannot be empty") private List<String> items;
-
@NotBlank:字段不能为
null
,且去掉首尾空格后,必须至少有一个字符。常用于校验字符串。@NotBlank(message = "Email cannot be blank") private String email;
-
@Size:校验字符串、集合、数组的大小或长度。
@Size(min = 2, max = 30, message = "Name must be between 2 and 30 characters") private String name;
-
@Min 和 @Max:校验数值型字段的最小值和最大值。
@Min(value = 18, message = "Age must be at least 18") @Max(value = 60, message = "Age must be less than 60") private int age;
-
@Email:校验是否为合法的电子邮件格式。
@Email(message = "Email should be valid") private String email;
-
@Pattern:使用正则表达式校验字符串的格式。
@Pattern(regexp = "^\\d{10}$", message = "Phone number must be 10 digits") private String phoneNumber;
-
@Past 和 @Future:校验日期字段是否在过去或未来。
@Past(message = "Birthday must be in the past") private LocalDate birthday;@Future(message = "Appointment date must be in the future") private LocalDate appointmentDate;
-
@AssertTrue 和 @AssertFalse:校验布尔类型字段是否为
true
或false
。@AssertTrue(message = "Must agree to terms") private boolean agreedToTerms;
2. 组合注解
可以组合多个注解来实现复杂的校验规则。例如,校验一个字段既不为空,又必须符合特定格式:
@NotBlank(message = "Username cannot be blank")
@Pattern(regexp = "^[a-zA-Z0-9]{3,}$", message = "Username must be alphanumeric and at least 3 characters long")
private String username;
3. 分组校验(@Validated)
分组校验可以根据不同场景应用不同的校验规则。需要结合 @Validated
注解来实现。
-
定义分组接口:
public interface CreateGroup {} public interface UpdateGroup {}
-
在实体类中应用分组:
@NotNull(groups = UpdateGroup.class, message = "Id cannot be null when updating") private Long id;@NotBlank(groups = CreateGroup.class, message = "Name cannot be blank when creating") private String name;
-
在 Controller 方法中指定分组:
@PostMapping("/create") public ResponseEntity<String> createUser(@Validated(CreateGroup.class) @RequestBody User user) {// 校验仅针对 CreateGroup 分组return ResponseEntity.ok("User created"); }@PutMapping("/update") public ResponseEntity<String> updateUser(@Validated(UpdateGroup.class) @RequestBody User user) {// 校验仅针对 UpdateGroup 分组return ResponseEntity.ok("User updated"); }
4. 自定义校验注解
如果内置的校验注解不能满足需求,可以创建自定义校验注解。
-
创建注解:
@Target({ElementType.FIELD, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = MyCustomValidator.class) public @interface MyCustomValidation {String message() default "Invalid value";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {}; }
-
实现校验逻辑:
public class MyCustomValidator implements ConstraintValidator<MyCustomValidation, String> {@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {// 校验逻辑,例如:字符串必须包含 "valid"return value != null && value.contains("valid");} }
-
使用自定义注解:
@MyCustomValidation(message = "The value must contain 'valid'") private String customField;
通过这些校验注解和机制,可以在 Spring Boot 中高效地处理参数校验逻辑,确保应用的输入数据符合预期。
通过以上就可以正常使用注解在SpringBoot中完成参数校验功能了!感谢大家的收看 如果感觉有帮助请留下小星星
相关文章:
SpringBoot参数校验详解
前言 在web开发时,对于请求参数,一般上都需要进行参数合法性校验的,原先的写法时一个个字段一个个去判断,这种方式太不通用了,Hibernate Validator 是 Bean Validation 规范的参考实现,用于在 Java 应用中…...
安全基础学习-SHA-1(Secure Hash Algorithm 1)算法
SHA-1(Secure Hash Algorithm 1)是一种密码学哈希函数,用于将任意长度的输入数据(消息)转换成一个固定长度的输出(哈希值或摘要),长度为160位(20字节)。SHA-1的主要用途包括数据完整性验证、数字签名、密码存储等。 1、SHA-1 的特性 定长输出:无论输入数据长度是多…...

leetcode350. 两个数组的交集 II,哈希表
leetcode350. 两个数组的交集 II 给你两个整数数组 nums1 和 nums2 ,请你以数组形式返回两数组的交集。返回结果中每个元素出现的次数,应与元素在两个数组中都出现的次数一致(如果出现次数不一致,则考虑取较小值)。可…...

基于YOLOv8的缺陷检测任务模型训练
文章目录 一、引言二、环境说明三、缺陷检测任务模型训练详解3.1 PCB数据集3.1.1 数据集简介3.1.2 数据集下载3.1.3 构建yolo格式的数据集 3.2 基于ultralytics训练YOLOv83.2.1 安装依赖包3.2.2 ultralytics的训练规范说明3.2.3 创建训练配置文件3.2.4 下载预训练模型3.2.5 训练…...

【upload]-ini-[SUCTF 2019]CheckIn-笔记
上传图片木马文件后看到,检查的文件内容,包含<? 一句话木马提示 检查的文件格式 用如下图片木马,加上GIF89a绕过图片和<?检查 GIF89a <script languagephp>eval($_POST[cmd])</script> .user.ini实际上就是一个可以由用…...
uniapp条件编译使用教学(#ifdef、#ifndef)
#ifdef //仅在xxx平台使用#ifndef //除了在xxx平台使用#endif // 结束 标识平台APP-PLUSAPPMP微信小程序/支付宝小程序/百度小程序/头条小程序/QQ小程序MP-WEIXIN微信小程序MP-ALIPAY支付宝小程序MP-BAIDU百度小程序MP-TOUTIAO头条小程序MP-QQQQ小程序H5H5APP-PLUS-NVUEApp nv…...

NXP i.MX8系列平台开发讲解 - 4.1.2 GNSS 篇(二) - 卫星导航定位原理
专栏文章目录传送门:返回专栏目录 Hi, 我是你们的老朋友,主要专注于嵌入式软件开发,有兴趣不要忘记点击关注【码思途远】 文章目录 关注星号公众号,不容错过精彩 作者:HywelStar Hi, 我是你们的老朋友HywelStar, 根…...
怎样在 SQL 中对一个包含销售数据的表按照销售额进行降序排序?
在当今数字化商业的浪潮中,数据就是企业的宝贵资产。对于销售数据的有效管理和分析,能够为企业的决策提供关键的支持。而在 SQL 中,对销售数据按照销售额进行降序排序,是一项基础但极其重要的操作。 想象一下,您面前有…...

DIAdem 与 LabVIEW
DIAdem 和 LabVIEW 都是 NI (National Instruments) 公司开发的产品,尽管它们有不同的核心功能和用途,但它们在工程、测试和测量领域中常常一起使用,以形成一个完整的数据采集、分析、处理和报告生成的解决方案。 1. 功能和用途 LabVIEW (Lab…...

UE虚幻引擎可以云渲染吗?应用趋势与挑战了解
虚幻云渲染技术是基于虚幻引擎的云端渲染技术,将虚幻引擎的渲染计算任务通过云计算的方式进行处理和渲染、并将渲染结果传输到终端设备上进行展示。虚幻引擎云渲染技术在近年来得到了迅猛的发展,并在各个领域得到了广泛的应用,包括游戏、电影…...

实战分享:DefenderUI在企业环境中的部署与应用
前言 想象一下,你的电脑就像一座坚固的城堡,但城门却时常被一些不速之客窥探甚至企图入侵;Defender,作为城堡自带的守护者,实力自然不容小觑;但你是否觉得它有时候太过低调,有些隐藏技能还没完…...
中英双语介绍金融经济中的鹰派 (Hawkish)和鸽派 (Dovish)
中文版 在金融和经济政策中,“鹰派”和“鸽派”是两种对货币政策和经济管理有不同立场的群体。 鹰派 (Hawkish) 鹰派倾向于担心通货膨胀的风险,通常支持较高的利率和更紧的货币政策,以防止经济过热和控制物价上涨。具体特征包括࿱…...
Android 开发中常用的布局类型及其选择指南
在 Android 开发过程中,选择正确的布局类型对于构建高效、美观且响应式的用户界面至关重要。本文将介绍 Android 中几种最常用的布局类型,并对比它们的特点和适用场景,帮助开发者们做出明智的选择。 1. LinearLayout - 线性布局 特点: LinearLayout 是最基本的布局类型之一…...

短视频SDK解决方案,降低行业开发门槛
美摄科技匠心打造了一款集前沿技术与极致体验于一体的短视频SDK解决方案,它不仅重新定义了短视频创作的边界,更以行业标杆级的短视频特效,让每一帧画面都闪耀不凡光芒。 【技术赋能,创意无限】 美摄科技的短视频SDK,…...

【C++】String常见函数用法
一、string类对象的常见构造 我们可采取以下的方式进行构造,以下是常用的接口: //生成空字符串 string; //拷贝构造函数 string(const string& str); //用C-string来构造string类对象 string(const char* s); //string类对象中包含n个字符c strin…...
LeetCode49.字母异位词分组
题目大意 给你一个字符串数组,请你将字母异位词组合在一起。可以按任意顺序返回结果列表。 字母异位词是由重新排列源单词的所有字母得到的一个新单词。 思路分析 示例 1: 输入: strs ["eat", "tea", "tan", "ate", &…...
Nginx日志按天分割
需求、日志按照天的单位进行分割存储。 如果你直接百度,可能会搜到很多教你用各种脚本或是三方插件来按天分割的,这边我用nginx服务本身来分割日志。 方法一 通过使用 $time_iso8601 变量和 map 指令,实现了日志文件按天分割的功能。以下是…...
文本摘要简介
文本摘要是从一段长文本中提取出最重要的信息,并生成一个简短而有意义的摘要。这个过程可以分为两种主要方法: 抽取式摘要(Extractive Summarization):从原文中直接提取出关键句子或段落,组成摘要…...
3.MySQL面试题之Redis 和 Mysql 如何保证数据一致性?
Redis 和 MySQL 数据一致性是分布式系统中的一个常见挑战。保证数据一致性通常涉及几种策略,我会详细解释这些策略并提供相应的代码示例。 先更新数据库,再更新缓存 这种方法先更新 MySQL,然后更新或删除 Redis 缓存。 Transactional publ…...
浅谈TCP协议、UDP协议
一、介绍说明 TCP(传输控制协议) 面向连接:TCP在数据传输之前必须建立连接。这通过一个称为三次握手的过程来完成,确保连接的两端都准备好进行数据传输。 可靠性:TCP提供可靠的数据传输,确保数据包正确无…...

YSYX学习记录(八)
C语言,练习0: 先创建一个文件夹,我用的是物理机: 安装build-essential 练习1: 我注释掉了 #include <stdio.h> 出现下面错误 在你的文本编辑器中打开ex1文件,随机修改或删除一部分,之后…...
C++.OpenGL (10/64)基础光照(Basic Lighting)
基础光照(Basic Lighting) 冯氏光照模型(Phong Lighting Model) #mermaid-svg-GLdskXwWINxNGHso {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-GLdskXwWINxNGHso .error-icon{fill:#552222;}#mermaid-svg-GLd…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践
6月5日,2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席,并作《智能体在安全领域的应用实践》主题演讲,分享了在智能体在安全领域的突破性实践。他指出,百度通过将安全能力…...
MySQL中【正则表达式】用法
MySQL 中正则表达式通过 REGEXP 或 RLIKE 操作符实现(两者等价),用于在 WHERE 子句中进行复杂的字符串模式匹配。以下是核心用法和示例: 一、基础语法 SELECT column_name FROM table_name WHERE column_name REGEXP pattern; …...

深入解析C++中的extern关键字:跨文件共享变量与函数的终极指南
🚀 C extern 关键字深度解析:跨文件编程的终极指南 📅 更新时间:2025年6月5日 🏷️ 标签:C | extern关键字 | 多文件编程 | 链接与声明 | 现代C 文章目录 前言🔥一、extern 是什么?&…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
Spring AI与Spring Modulith核心技术解析
Spring AI核心架构解析 Spring AI(https://spring.io/projects/spring-ai)作为Spring生态中的AI集成框架,其核心设计理念是通过模块化架构降低AI应用的开发复杂度。与Python生态中的LangChain/LlamaIndex等工具类似,但特别为多语…...

视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
解决:Android studio 编译后报错\app\src\main\cpp\CMakeLists.txt‘ to exist
现象: android studio报错: [CXX1409] D:\GitLab\xxxxx\app.cxx\Debug\3f3w4y1i\arm64-v8a\android_gradle_build.json : expected buildFiles file ‘D:\GitLab\xxxxx\app\src\main\cpp\CMakeLists.txt’ to exist 解决: 不要动CMakeLists.…...

Unity UGUI Button事件流程
场景结构 测试代码 public class TestBtn : MonoBehaviour {void Start(){var btn GetComponent<Button>();btn.onClick.AddListener(OnClick);}private void OnClick(){Debug.Log("666");}}当添加事件时 // 实例化一个ButtonClickedEvent的事件 [Formerl…...