Spring Boot项目中校验器的使用与注意事项

Spring Boot项目中校验器的使用与注意事项

Spring Boot为开发者提供了强大而灵活的校验机制,通过使用校验器(Validator),我们能够在应用程序中方便地进行数据验证和错误处理。本文将深入介绍Spring Boot中校验器的使用方法,同时探讨在实际项目中需要注意的一些细节。

1. 校验器的基本概念

在Spring Boot中,校验器是通过@Valid注解与javax.validation包下的相关注解配合使用的。这些注解包括@NotNull@NotEmpty@Size@Pattern等,用于在实体类字段上定义校验规则。

首先,我们需要在实体类的字段上添加相应的注解,示例代码如下:

public class User {@NotNull(message = "姓名不能为空")private String name;@NotEmpty(message = "邮箱不能为空")@Email(message = "邮箱格式不正确")private String email;// 其他字段和方法
}

在这个例子中,我们使用了@NotNull注解来标记name字段不能为空,而@NotEmpty@Email注解则用于验证email字段不能为空且必须符合邮箱格式。

2. 控制器中的校验

在Spring Boot控制器中,我们可以通过在方法参数前加上@Valid注解,告诉Spring Boot要对该参数进行校验。如果校验不通过,将会触发MethodArgumentNotValidException异常,我们可以通过捕获该异常进行错误处理。

@RestController
@RequestMapping("/users")
public class UserController {@PostMappingpublic ResponseEntity<String> createUser(@Valid @RequestBody User user) {// 处理用户创建逻辑return ResponseEntity.ok("User created successfully");}@ExceptionHandler(MethodArgumentNotValidException.class)public ResponseEntity<String> handleValidationExceptions(MethodArgumentNotValidException ex) {List<String> errors = new ArrayList<>();ex.getBindingResult().getAllErrors().forEach(error -> errors.add(error.getDefaultMessage()));return ResponseEntity.badRequest().body(String.join(", ", errors));}
}

在上述代码中,createUser方法的@Valid注解告诉Spring Boot对User对象进行校验,如果校验失败,将触发MethodArgumentNotValidException异常。通过handleValidationExceptions方法,我们可以捕获并处理校验异常,返回自定义的错误信息。

3. 自定义校验器

除了使用内置的校验注解外,我们还可以创建自定义的校验器来满足特定需求。自定义校验器需要实现ConstraintValidator接口,并在需要校验的字段上使用@Constraint注解进行标记。

以下是一个自定义校验器的简单例子,用于验证密码是否符合一定的安全规范:

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PasswordValidator.class)
public @interface Password {String message() default "密码不符合安全规范";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};
}

然后,实现ConstraintValidator接口:

public class PasswordValidator implements ConstraintValidator<Password, String> {@Overridepublic void initialize(Password constraintAnnotation) {// 初始化操作}@Overridepublic boolean isValid(String password, ConstraintValidatorContext context) {// 实际的校验逻辑return password != null && password.matches("^(?=.*[0-9])(?=.*[a-zA-Z])(?=.*[@#$%^&+=])(?=\\S+$).{8,}$");}
}

在这个例子中,我们定义了一个Password注解,并创建了PasswordValidator类来实现密码的安全性校验。可以在实体类中使用该注解:

public class User {@Passwordprivate String password;// 其他字段和方法
}

4. 校验器的注意事项

在使用校验器时,我们需要注意以下几点:

4.1. 分组校验

Spring Boot支持使用分组(groups)对不同的校验场景进行分组校验。例如,我们可以在User实体类中定义两个分组:CreateUpdate,并在控制器方法中指定使用哪个分组进行校验:

public class User {@NotNull(groups = Create.class, message = "姓名不能为空")private String name;@NotEmpty(groups = Create.class, message = "邮箱不能为空")@Email(groups = Create.class, message = "邮箱格式不正确")private String email;@NotNull(groups = Update.class, message = "用户ID不能为空")private Long userId;// 其他字段和方法
}@RestController
@RequestMapping("/users")
public class UserController {@PostMappingpublic ResponseEntity<String> createUser(@Validated(Create.class) @RequestBody User user) {// 创建用户逻辑return ResponseEntity.ok("User created successfully");}@PutMapping("/{id}")public ResponseEntity<String> updateUser(@PathVariable Long id, @Validated(Update.class) @RequestBody User user) {// 更新用户逻辑return ResponseEntity.ok("User updated successfully");}
}

4.2. 全局异常处理

在实际项目中,为了更好地处理校验失败的情况,我们可以通过全局异常处理器统一处理校验异常。可以创建一个ResponseEntityExceptionHandler类,继承自ResponseEntityExceptionHandler,在其中定义对MethodArgumentNotValidException异常的处理逻辑:

@ControllerAdvice
public class GlobalExceptionHandler extends ResponseEntityExceptionHandler {@Overrideprotected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) {List<String> errors = new ArrayList<>();ex.getBindingResult().getAllErrors().forEach(error -> errors.add(error.getDefaultMessage()));return ResponseEntity.badRequest().body(String.join(", ", errors));}
}

这样,当任何控制器方法中的校验失败时,都会被统一处理并返回友好的错误

5. Maven依赖配置

在Spring Boot项目中使用校验器,我们需要确保项目中包含相关的校验器和验证框架的依赖。通常,我们可以在项目的pom.xml文件中添加以下依赖:

<dependencies><!-- Spring Boot Starter Web 包含了 Spring MVC 和 Tomcat --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Hibernate Validator,Spring Boot 默认的校验器实现 --><dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId></dependency><!-- Validation API,提供了校验注解和相关 API --><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId></dependency><!-- 添加 Tomcat 依赖,用于支持嵌入式 Tomcat --><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-core</artifactId></dependency><!-- Spring Boot Starter Test,用于测试 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>

在这个依赖配置中,主要包括了Spring Boot Starter Web、Hibernate Validator、Validation API等依赖。这些依赖会为我们提供在Spring Boot项目中使用校验器所需的基础支持。

确保项目中的pom.xml文件中包含上述依赖,并执行Maven构建操作,使得相关依赖能够被正确引入项目。

6. 自定义错误消息

在校验器中,我们可以通过message属性为每个校验注解指定自定义的错误消息。但为了更好地维护和统一管理错误消息,我们可以将错误消息定义在属性文件中,并通过ValidationMessages.properties文件引用。

首先,我们在src/main/resources目录下创建ValidationMessages.properties文件:

# ValidationMessages.properties# User类校验错误消息
user.name.notNull=姓名不能为空
user.email.notEmpty=邮箱不能为空
user.email.emailFormat=邮箱格式不正确
user.userId.notNull=用户ID不能为空# PasswordValidator校验错误消息
password.invalid=密码不符合安全规范

接着,我们可以在实体类中引用这些错误消息:

public class User {@NotNull(message = "{user.name.notNull}")private String name;@NotEmpty(message = "{user.email.notEmpty}")@Email(message = "{user.email.emailFormat}")private String email;@NotNull(groups = Update.class, message = "{user.userId.notNull}")private Long userId;// 其他字段和方法
}

这样做的好处是,可以更灵活地管理错误消息,便于国际化和维护。

7. 使用场景和建议

在实际项目中,校验器是确保数据的完整性和一致性的重要工具。以下是一些建议和使用场景:

  • 请求参数校验:对于前端传递的请求参数,使用校验器确保参数的有效性,防止恶意输入和错误请求。

  • 实体对象校验:对于实体对象的属性,使用校验器来确保数据的完整性,例如在保存用户信息时,确保姓名和邮箱不为空。

  • 分组校验:当同一个实体类在不同场景下需要进行不同的校验时,使用分组校验可以灵活处理不同的校验规则。

  • 全局异常处理:为了更好地处理校验失败的情况,建议使用全局异常处理器来统一处理校验异常,返回友好的错误信息。

  • 自定义校验器:当内置的校验注解无法满足特定需求时,可以通过创建自定义校验器来实现定制化的校验逻辑。

8. 注意事项:@NotBlank 和 @NotEmpty 的使用

在Spring Boot中,@NotBlank@NotEmpty是两个常用的校验注解,用于验证字符串类型的字段。然而,在使用这两个注解时,我们需要注意一些细节和差异。

8.1. @NotBlank 注解

@NotBlank注解用于验证字符串非null,且去除首尾空白字符后长度必须大于0。以下是一个示例:

public class User {@NotBlank(message = "姓名不能为空")private String name;// 其他字段和方法
}

在这个例子中,如果namenull、空字符串或者只包含空白字符,都将触发校验失败。

8.2. @NotEmpty 注解

@NotEmpty注解用于验证集合、数组、Map或者字符串非null,且长度必须大于0。以下是一个示例:

public class User {@NotEmpty(message = "邮箱不能为空")private String email;// 其他字段和方法
}

在这个例子中,如果emailnull、空字符串或者只包含空白字符,都将触发校验失败。

8.3. 注意事项

8.3.1. 空格的处理

使用@NotBlank@NotEmpty时,需要注意空格的处理。这两个注解会去除字符串首尾的空格字符,然后再进行非空判断。因此,如果字符串只包含空格,仍然会被认为是空的。

8.3.2. 适用场景
  • 使用@NotBlank时,适用于要求字符串非null且去除首尾空白字符后长度大于0的情况,例如姓名、密码等。

  • 使用@NotEmpty时,适用于要求字符串非null且长度大于0的情况,例如邮箱、电话号码等。

8.3.3. 集合和数组

注意,@NotEmpty不仅可以用于字符串,还可以用于集合、数组和Map的校验。在校验集合、数组和Map时,@NotEmpty要求其非null且元素个数大于0。

public class User {@NotEmpty(message = "角色列表不能为空")private List<String> roles;// 其他字段和方法
}

8.4. 示例说明

让我们通过一个示例来说明@NotBlank@NotEmpty的使用:

public class User {@NotBlank(message = "姓名不能为空")private String name;@NotEmpty(message = "邮箱不能为空")private String email;@NotEmpty(message = "角色列表不能为空")private List<String> roles;// 其他字段和方法
}

在这个例子中,name使用了@NotBlank,要求非null且去除首尾空白字符后长度大于0。emailroles使用了@NotEmpty,要求非null且长度大于0。

@RestController
@RequestMapping("/users")
public class UserController {@PostMappingpublic ResponseEntity<String> createUser(@Valid @RequestBody User user) {// 处理用户创建逻辑return ResponseEntity.ok("User created successfully");}@ExceptionHandler(MethodArgumentNotValidException.class)public ResponseEntity<String> handleValidationExceptions(MethodArgumentNotValidException ex) {List<String> errors = new ArrayList<>();ex.getBindingResult().getAllErrors().forEach(error -> errors.add(error.getDefaultMessage()));return ResponseEntity.badRequest().body(String.join(", ", errors));}
}

在控制器中,通过@Valid注解对User对象进行校验,校验失败时将触发MethodArgumentNotValidException异常,然后通过全局异常处理器捕获并返回自定义的错误信息。

通过以上说明,希望读者能够更加清晰地了解在Spring Boot项目中使用@NotBlank@NotEmpty时需要注意的细节和使用场景。这两个注解在对字符串进行非空校验时是十分实用的,能够有效防止一些潜在的错误。

9. Maven 依赖版本

在使用 @NotBlank@NotEmpty 这两个校验注解时,需要确保相关的 Maven 依赖版本匹配。这涉及到 Validation API、Hibernate Validator 的版本兼容性。

9.1. 配置 Maven 依赖

通常,我们可以在项目的 pom.xml 文件中配置如下 Maven 依赖:

<dependencies><!-- Spring Boot Starter Web 包含了 Spring MVC 和 Tomcat --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Hibernate Validator,Spring Boot 默认的校验器实现 --><dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><!-- 需要保持版本与 Validation API 一致 --><version>6.1.7.Final</version></dependency><!-- Validation API,提供了校验注解和相关 API --><dependency><groupId>javax.validation</groupId><artifactId>validation-api</artifactId><!-- 需要保持版本与 Hibernate Validator 一致 --><version>2.0.1.Final</version></dependency><!-- 添加 Tomcat 依赖,用于支持嵌入式 Tomcat --><dependency><groupId>org.apache.tomcat.embed</groupId><artifactId>tomcat-embed-core</artifactId></dependency><!-- Spring Boot Starter Test,用于测试 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>

9.2. 注意版本兼容性

上述配置中,需要保持 Hibernate Validator 的版本与 Validation API 的版本一致。通常,你可以在 Maven 仓库中查找最新的版本。

当前示例中使用的版本分别是 Hibernate Validator 6.1.7.Final 和 Validation API 2.0.1.Final。请根据实际情况,查看 Maven 仓库或者相关文档,确保版本的兼容性。

9.3. Maven 依赖冲突

在项目中,有时可能会遇到 Maven 依赖冲突的情况,尤其是当多个依赖项引入了相同的库但版本不同。为了解决这类问题,你可以使用 Maven 的 mvn dependency:tree 命令查看项目依赖树,并逐步调整版本以解决冲突。

mvn dependency:tree

通过保持版本一致,可以避免由于依赖版本不匹配而导致的运行时错误和行为不一致的问题。

9.4. 版本更新

由于技术生态系统不断更新,建议定期检查相关库的最新版本,以获得新功能、修复已知问题和提高安全性。

总之,确保在使用 @NotBlank@NotEmpty 这两个校验注解时,相关的 Maven 依赖版本能够保持兼容性,这对项目的稳定性和正常运行是非常重要的。

10. 总结

在Spring Boot项目中,使用校验器是确保数据完整性和一致性的关键工具。@NotBlank@NotEmpty 是两个常用的校验注解,用于验证字符串类型的字段。通过合理使用这两个注解,我们能够在应用程序中轻松进行数据验证和错误处理。

总结起来,我们在本文中学到了以下重要知识点:

  1. 校验器基本概念:使用 @Valid 注解结合 javax.validation 包下的相关注解,可以对实体类进行简单而强大的校验。

  2. 控制器中的校验:通过在控制器方法参数前加上 @Valid 注解,可以触发校验,并通过异常处理器统一处理校验失败的情况。

  3. 自定义校验器:通过实现 ConstraintValidator 接口,可以创建自定义的校验器来满足特定需求。

  4. Maven依赖配置:确保项目中包含正确版本的 Spring Boot Starter Web、Hibernate Validator 和 Validation API 等依赖,以支持校验功能。

  5. 自定义错误消息:将错误消息定义在属性文件中,实现错误消息的统一管理和维护。

  6. @NotBlank 和 @NotEmpty 的使用注意事项:注意空格的处理、适用场景以及集合和数组的校验。

  7. Maven 依赖版本:保持 Hibernate Validator 和 Validation API 版本一致,防止版本冲突导致的问题。

在实际项目中,根据具体的业务需求和数据模型,选择适当的校验注解以及合适的校验器,能够有效提高系统的健壮性和可维护性。通过全面了解校验器的使用方法和注意事项,希望读者能够在项目中正确、高效地应用校验机制,确保数据的合法性和安全性。

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

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

相关文章

go如何终止多个for select循环嵌套

空山新雨后&#xff0c;天气晚来秋。 目录 分类说明 总结 分类说明 for select循环嵌套&#xff0c;如何终止&#xff1f;上代码&#xff1a; stop : make(chan struct{})go func() {for i : 1; i < 3; i {fmt.Println("writed ", i)time.Sleep(time.Second * …

「HDLBits题解」Alwaysblock2

本专栏的目的是分享可以通过HDLBits仿真的Verilog代码 以提供参考 各位可同时参考我的代码和官方题解代码 或许会有所收益 题目链接&#xff1a;Alwaysblock2 - HDLBits // synthesis verilog_input_version verilog_2001 module top_module(input clk,input a,input b,output…

phpcms v9外链文章获取点击量

默认phpcms v9的外链文章因为直接跳转&#xff08;不进入详情页模板&#xff09;&#xff0c;导致外链文章的点击量一直是0&#xff0c;而我们有时需要按点击量排行或者排序的时候&#xff0c;就有问题了。 这里我们借助系统自带的点击量接口api来获取&#xff1a; 一、前台JS…

【随笔】遗传算法优化的BP神经网络(随笔,不是很详细)

文章目录 一、算法思想1.1 BP神经网络1.2 遗传算法1.3 遗传算法优化的BP神经网络 二、代码解读2.1 数据预处理2.2 GABP2.3 部分函数说明 一、算法思想 1.1 BP神经网络 BP神经网络&#xff08;Backpropagation Neural Network&#xff0c;反向传播神经网络&#xff09;是一种监…

Linux第21步_取消鼠标中键的复制粘贴功能

在ubuntu18.04操作系统中&#xff0c;选中文本后&#xff0c;若按下鼠标中键&#xff0c;就可以执行复制粘贴&#xff0c;相当于 CtrlshiftC 后又按了 CtrlshiftV。在Linux系统中&#xff0c;基本上都是这么配置的。在windows系统中&#xff0c;我们习惯用Ctrl-C复制&#xff0…

普通人想通过抖音赚钱要先知道这4点

1.变现方式 想做抖音首先要想好变现路径以及通过什么方式变现。做抖音就是在经营某一类人群&#xff0c;因为人群绑定了精准标签&#xff0c;系统推送的精准又绑定了变现。所以要明确你经营的目标人群是谁&#xff0c;你在做谁的生意&#xff0c;你要赚谁的钱。他们的年龄、收…

OpenCV-Python的版本介绍及区别

OpenCV-Python版本介绍 OpenCV-Python有多个版本&#xff0c;每个版本都有其特定的功能和改进。以下是一些常见OpenCV-Python版本及其介绍和区别&#xff1a; OpenCV-Python 2.x版本 这是OpenCV-Python的旧版本&#xff0c;支持Python 2.x。它包含了许多传统的计算机视觉功能&…

可盐可甜的红色马甲背心

膨体棉腈面料不易皱&#xff0c;搭配阿兰花菱形镂空设计 真的绝绝子&#xff0c;红色吸睛又美观 随便搭配一件衬衫去穿&#xff0c;自带文艺气息 氛围感直接拉满 出街拍照很出片&#xff0c;时髦又气质 女孩子的甜美&#xff0c;温柔等都可以突显 有喜欢的可以尝试一下哟…

超维空间M1无人机使用说明书——61、ROS无人机物体识别与精准投放

引言&#xff1a;基于空中物流的项目背景。我们提供了使用基于诗句的物体识别和精准投放、降落。实现原理如下&#xff1a; 1、在ROS下使用机载电脑实现物体识别 2、记载电脑根据反馈的位置发布运动控制指令 3、PX4解析机载电脑发布的命令&#xff0c;作出运动控制 4、设置…

将抖音视频转成MP3并下载

这篇是在上一篇的基础上写的&#xff0c;这篇负责抖音作者详情页的视频转声音提取&#xff0c;这篇需要用到后端。 本地启动后端后&#xff0c;在控制台输入对应代码&#xff0c;即可实现hover在封面上&#xff0c;按d一键下载音频 控制台代码 // 获取作者的视频列表var liEle…

【蓝桥备赛】特殊时间——时间日期类问题

题目链接 特殊时间 个人思路 枚举年份范围比较广&#xff0c;考虑略微复杂&#xff1b;枚举月日重点只要看月份需要枚举12个月&#xff1b;枚举时间有24小时。 综合起来看&#xff0c;枚举月日的讨论应该比较少。 详细分析看注释 参考代码 Java public class Main {publi…

LeetCode 2085. 统计出现过一次的公共字符串

目录 一、题目 1、题目描述 2、接口描述 3、原题链接 二、解题报告 1、思路分析 2、复杂度 3、代码详解 C代码 ​Python3代码 一、题目 1、题目描述 给你两个字符串数组 words1 和 words2 &#xff0c;请你返回在两个字符串数组中 都恰好出现一次 的字符串的数目。 2…

我的创作纪念日(随便唠唠)

机缘 我在CSDN上面发表文章只是一时兴起&#xff0c;想着可以当作记录学习知识的一个笔记使用&#xff0c;并且我写的内容通常是我学习一段时间之后&#xff0c;经过了一段时间的沉淀&#xff08;这个时间通常是三个月到半年&#xff09;&#xff0c;觉得理解的够深刻之后才会…

思科无线AP 2802无法注册,手工指定控制器的IP

背景 Cisco AP 2802I Default username and password: Cisco Cisco 无法注册成功到wlc 5520上&#xff0c;AP上红灯一直闪烁。 Console连接AP&#xff0c;发现有获得Ip&#xff0c;但因为跨3层又没有dhcp option 43下发WLC IP&#xff0c;所以无法注册成功 。 获得IP地址&…

Docker与微服务实战(高级篇)- 【上】

Docker与微服务实战&#xff08;高级篇&#xff09;- 【上】 一、Docker复杂安装详说1.1 Mysql主从复制--原理-【尚硅谷Mysql高级篇】1.2 Mysql主从复制--【一主一从】搭建步骤1.2.1新建--【主服务器】--容器实例--33071.2.2.进入/app/mysql-master/conf目录下新建my.cnf1.2.3.…

Scipy 中级教程——信号处理

Python Scipy 中级教程&#xff1a;信号处理 Scipy 的信号处理模块提供了丰富的工具&#xff0c;用于处理和分析信号数据。在本篇博客中&#xff0c;我们将深入介绍 Scipy 中的信号处理功能&#xff0c;并通过实例演示如何应用这些工具。 1. 信号生成与可视化 首先&#xff…

【算法】简单的二分查找算法

一个简单的二分查找算法&#xff1a; import java.util.Arrays; public class BinarySearch {public static int rank(int key,int[] a){int lo0;int hia.length-1;while (lo<hi){int midlo(hi-lo)/2;if (key<a[mid])himid-1;else if (key>a[mid])lomid1;else return …

嵌入式linux 编译qt5(以v851s为例)

本文参考Blev大神的博客&#xff1a;Yuzuki Lizard V851S开发板 --移植 QT5.12.9教程&#xff08;群友Blev提供&#xff09; - Allwinner / 柚木PI-V851S - 嵌入式开发问答社区 (100ask.net) 一. 环境准备 1.下载qt5源码&#xff1a;Open Source Development | Open Source …

XXL-JOB相关问题及答案(2024)

1、XXL-JOB是什么&#xff1f;它的作用是什么&#xff1f; XXL-JOB是一个分布式任务调度平台&#xff0c;用于实现任务的定时调度、任务执行和任务监控。它具有可视化的任务管理界面&#xff0c;支持多种任务调度方式&#xff0c;并提供任务执行结果的监控和告警功能。XXL-JO…

okhttpclient.setsslsocketfactory 报错解决

以前一直都用HttpUrlConnection这个类来做通信和进行文件下载&#xff0c;apk更新升级等。 后续因为更新apk的时候包体积较大&#xff0c;网络不好的时候&#xff0c;用HttpUrlConnection偶尔会下载失败&#xff0c;于是下载更新apk就改为了okhtt3这个库&#xff0c;其他业务请…