Spring Validation 校验 ( 一 )

news/2025/1/15 15:35:56/

Spring Validation 是 Spring Framework 的一部分,它提供了一种简单的方式来验证 Java 对象的数据。Spring Validation 基于 JSR 303/JSR 349(也称为 Bean Validation)规范,允许开发者使用注解来定义对象的约束条件,从而简化了验证逻辑的编写。

1.导入依赖

    <!-- Spring Boot Starter Web  依赖web环境 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- Spring Boot Starter Validation --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency><!-- https://mvnrepository.com/artifact/org.hibernate.validator/hibernate-validator --><dependency><groupId>org.hibernate.validator</groupId><artifactId>hibernate-validator</artifactId><version>8.0.1.Final</version></dependency>

spring-boot-starter-validationhibernate-validator 在 Spring Boot 中扮演着不同的角色,但它们紧密相关。下面是两者之间的主要区别:

  • spring-boot-starter-validation 提供了 Spring Boot 中 Bean Validation 的自动配置和支持。它还提供了对 Spring MVC 控制器中验证的支持,例如通过 @Valid@Validated 注解来验证请求体和方法参数。
  • hibernate-validator 是一个具体的 Bean Validation 实现,它提供了验证逻辑和标准的验证注解。它提供了所有标准的验证注解(如 @NotNull, @Size, @Pattern 等)的实现。支持创建自定义验证注解和相应的验证器实现。
  • 通常情况下,只需要添加 spring-boot-starter-validation 即可,因为它会自动包含 Hibernate Validator 或其他 Bean Validation 实现。

2.标准注解

2.1.常用注解

  1. @Null : 指定字段必须为 null
  2. @NotNull : 指定字段不得为 null
  3. @NotBlank : 指定字符串必须不为空,且不全是空白字符。
  4. @NotEmpty : 指定字符串、数组、集合、Map 或其他可迭代类型必须不为空。
  5. @AssertFalse : 指定布尔值必须为 false
  6. @AssertTrue : 指定布尔值必须为 true
  7. @Min(value) : 指定数值必须大于等于指定的最小值。
  8. @Max(value) : 指定数值必须小于等于指定的最大值。
  9. @DecimalMin(value) : 指定数值必须大于等于指定的小数值。
  10. @DecimalMax(value) : 指定数值必须小于等于指定的小数值。
  11. @Size(min, max) : 指定字符串、数组、集合、Map 或其他可迭代类型的元素数量必须在指定范围内。
  12. @Digits(integer, fraction) : 指定数值的整数部分和小数部分的最大位数。
  13. @Past : 指定日期必须在过去。
  14. @Future : 指定日期必须在未来。
  15. @PastOrPresent : 指定日期必须在过去或现在。
  16. @FutureOrPresent : 指定日期必须在未来或现在。
  17. @Pattern(regexp) : 指定字符串必须匹配指定的正则表达式。
  18. @Positive : 指定数值必须大于 0。
  19. @PositiveOrZero : 指定数值必须大于等于 0。
  20. @Negative : 指定数值必须小于 0。
  21. @NegativeOrZero : 指定数值必须小于等于 0。
  22. @Email : 指定字符串必须是有效的电子邮件地址。
  23. @URL(protocol, host, port) : 指定字符串必须是有效的 URL。
  24. @CreditCardNumber : 指定字符串必须是有效的信用卡号码。
  25. @Length(min, max) : 指定字符串长度必须在指定范围内。
  26. @Range(min, max) : 指定数值必须在指定范围内。

2.2.使用案例

  1. 定义验证规则。

  2. 使用 @Valid 注解来验证控制器方法的参数。

  3. 处理验证错误。

  4. 实现额外的逻辑,如检查用户名是否唯一。

2.2.1.创建 User 类

定义一个 User 类,使用 Bean Validation 注解来定义验证规则:

java">import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.Size;public class User {@NotBlank(message = "用户名不能为空")@Size(min = 5, max = 20, message = "用户名长度应在5到20个字符之间")private String username;@NotBlank(message = "密码不能为空")@Size(min = 8, max = 32, message = "密码长度应在8到32个字符之间")private String password;@Email(message = "邮箱格式不正确")private String email;// 构造函数、getter 和 setter 省略
}
2.2.2.创建 UserRepository

创建一个简单的 UserServiceImpl ,用于模拟数据库操作:

java">import com.yuan.springvalidationdemo.domain.User;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl  {public boolean existsByUsername(String username){// 模拟数据库查询, 验证用户名是否已存在return false;}public void save(User user) {// 模拟保存用户}
}
2.2.3.创建 UserController

创建一个 UserController 类,用于处理用户的注册请求,并使用 @Valid 注解来验证传入的用户对象:

java">import com.yuan.springvalidationdemo.domain.User;
import com.yuan.springvalidationdemo.service.impl.UserServiceImpl;
import jakarta.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;@RestController
public class UserController {@Autowiredprivate UserServiceImpl userService;@PostMapping("/register")public ResponseEntity<String> register(@Valid @RequestBody User user, BindingResult result) {if (result.hasErrors()) {// 如果有验证错误,则返回错误信息StringBuilder errorMessage = new StringBuilder();result.getFieldErrors().forEach(error -> {errorMessage.append(error.getDefaultMessage()).append("\n");});return ResponseEntity.badRequest().body(errorMessage.toString());}// 检查用户名是否唯一if (userService.existsByUsername(user.getUsername())) {return ResponseEntity.badRequest().body("用户名已存在");}// 保存用户userService.save(user);return ResponseEntity.ok("注册成功");}
}
2.2.4.测试

运行 Spring Boot 应用程序,并发送 POST 请求到 /register 端点,测试不同的输入情况:

  • 正确的输入:

    • 发送一个包含有效用户名、密码和电子邮件的 JSON 对象。
    • 应该收到响应 “注册成功”。
  • 错误的输入:

    • 发送一个包含无效用户名、密码或电子邮件的 JSON 对象。
    • 应该收到响应,显示验证错误信息。
2.2.5.BindingResult 的作用

BindingResult 是 Spring MVC 中的一个接口,它用于收集和处理模型对象的绑定结果,包括验证错误和其他绑定过程中产生的问题。当你在控制器方法中使用 @Valid@Validated 注解来验证一个对象时,通常会将 BindingResult 作为一个额外的参数传递给该方法。

  1. 收集验证错误:
    • 当使用 @Valid@Validated 注解时,Spring 会自动调用验证器来验证对象。
    • 如果发现任何验证错误,这些错误会被收集到 BindingResult 对象中。
  2. 访问验证错误:
    • 你可以通过 BindingResult 对象来获取验证错误的详细信息。
    • 例如,你可以使用 hasErrors(), getFieldErrors(), getGlobalErrors() 等方法来检查是否有验证错误,以及获取特定字段的错误信息。
  3. 处理验证错误:
    • 一旦你获取到了验证错误,你可以根据需要处理这些错误。
    • 例如,你可以向客户端返回错误信息,或者在前端显示错误消息。

3.@Valid@Validated

@Valid@Validated 是 Spring Validation 中用于触发验证逻辑的注解。它们在不同的上下文中使用,并且有着细微的区别。

3.1.@Valid

  • 位置:

    • @Valid 注解可以放在控制器方法的参数上。
  • 作用:

    • 当一个对象被 @Valid 注解修饰时,Spring 会尝试对该对象进行验证。
    • 如果验证失败,即对象违反了定义的约束条件,那么 Spring 会将验证错误收集到 BindingResult 对象中。
    • 如果验证成功,方法将继续执行。
  • 使用场景:

    • 通常用于单个对象的验证。
    • 在控制器方法中,可以与 BindingResult 参数一起使用来处理验证错误。
java">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;
import javax.validation.constraints.NotEmpty;@RestController
public class UserController {@PostMapping("/register")public String register(@Valid @RequestBody User user, BindingResult result) {if (result.hasErrors()) {return "注册异常";}// 用户注册逻辑return "注册成功";}
}

3.2.@Validated

  • 位置:

    • @Validated 注解可以放在类级别或方法级别。
    • 当放在类级别时,表示该类的所有方法都需要进行验证。
    • 当放在方法级别时,表示该方法需要进行验证。
  • 使用场景:

    • 用于验证控制器类中的方法参数。

    • 通常不需要与 BindingResult 一起使用,因为验证错误通常由控制器类处理。

java">import com.yuan.springvalidationdemo.domain.User;
import jakarta.validation.Valid;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;@RestController
@Validated
public class UserController2 {@PostMapping("/register2")public String register(@Valid @RequestBody User user) {// 用户注册逻辑return "注册成功";}
}

3.3.比较

  • @Valid:

    • 用于单个对象的验证。
    • 通常与 BindingResult 一起使用来处理验证错误。
  • @Validated:

    • 用于验证控制器类中的方法参数。
    • 可以放在类级别或方法级别。
    • 通常不需要与 BindingResult 一起使用,因为验证错误通常由控制器类处理。

注意

  • 如果您只需要验证一个对象,通常使用 @Valid 就足够了。
  • 如果您想要对整个控制器类中的所有方法进行验证,可以使用 @Validated
  • 在实际应用中,@Valid 更常用,因为它提供了更细粒度的控制,并且与 BindingResult 结合使用时可以方便地处理验证错误。

http://www.ppmy.cn/news/1506767.html

相关文章

Java JVM中的栈空间怎么释放

在Java虚拟机 (JVM) 中&#xff0c;栈空间主要用于存储方法调用时的信息&#xff0c;例如局部变量、操作数栈、动态链接信息以及返回地址等。当一个方法被调用时&#xff0c;一个新的栈帧会在当前线程的栈中被创建&#xff1b;当该方法执行完毕后&#xff0c;这个栈帧就会被销毁…

【Python】Django Web 框架

一、常用的Web开发框架 1.Django Django是一个由Python写成的开放源代码的Web应用框架。这套框架的主要目标是使开发复杂、数据库驱动的网站变得简单。Django注重组件的重用性和“可拔插性”、敏捷开发和DRY(Dont Repeat Yourself)法则 2.Flask Flask是一个微型的Python开发…

DevExpress WPF中文教程:如何在GridControl中对数据排序、分组、过滤?

DevExpress WPF拥有120个控件和库&#xff0c;将帮助您交付满足甚至超出企业需求的高性能业务应用程序。通过DevExpress WPF能创建有着强大互动功能的XAML基础应用程序&#xff0c;这些应用程序专注于当代客户的需求和构建未来新一代支持触摸的解决方案。 无论是Office办公软件…

java控制台进阶知识

Java 控制台&#xff08;通常指的是标准输入 System.in 和标准输出 System.out&#xff09;是进行命令行交互的基本工具。对于基本的输入输出操作&#xff0c;Java 提供了 Scanner 类和 PrintStream 类等。但是&#xff0c;如果你想要实现更高级的功能&#xff0c;例如颜色输出…

SaaS 系统的详细讲解

SaaS 系统的详细讲解 目录 概述SaaS 的基本概念 2.1 什么是 SaaS2.2 SaaS 的优势2.3 SaaS 的挑战SaaS 架构设计 3.1 多租户架构3.2 数据隔离与安全3.3 可扩展性设计3.4 配置化与自定义SaaS 系统的关键组件 4.1 用户管理与认证4.2 计费与订阅管理4.3 数据存储与访问4.4 API 网关…

茶余饭后(四)

1&#xff0c;越来越安静 2&#xff0c;有计划&#xff0c;勤反思 3&#xff0c;骨子里不相信任何人 4&#xff0c;对未来有明确地目标 5&#xff0c;不再流泪&#xff0c;什么事都愿意自己去做 6&#xff0c;学会孤独&#xff0c;养成独立人格 7&#xff0c;做自己喜欢的…

【数据结构七夕专属版】单链表及单链表的实现【附源码和源码讲解】

本篇是博主在学习数据结构时的心得&#xff0c;希望能够帮助到大家&#xff0c;也许有些许遗漏&#xff0c;但博主已经尽了最大努力打破信息差&#xff0c;如果有遗漏还请见谅&#xff0c;嘻嘻&#xff0c;前路漫漫&#xff0c;我们一起前进&#xff01;&#xff01;&#xff0…

DITA发布PDF样式定制

- 1 - 概述 使用结构化写作/DITA写作&#xff0c;内容和样式是分离的。 编写的内容放在DITA文件中&#xff0c;样式是放在样式模板文件中。 而且针对不同的格式的输出&#xff08;如&#xff1a;PDF&#xff0c;MS Word&#xff09;&#xff0c;样式模板文件不同。 文档工程…