当前位置: 首页 > web >正文

Spring的 @Validate注解详细分析

在 Spring Boot 中,参数校验是保证数据合法性的重要手段。除了前面提到的@NotNull、@Size等基础注解外,JSR-303(Bean Validation 1.0)、JSR-349(Bean Validation 1.1)和 JSR-380(Bean Validation 2.0)规范还提供了大量常用的校验注解。下面详细介绍这些注解及其应用场景:

一、基础校验注解

1. 空值校验

注解

作用

@NotNull

验证对象不为null,但允许为空字符串("")或空集合。

@Null

验证对象必须为null。

@NotEmpty

验证字符串、集合、数组、Map 等不为null且长度 / 大小大于 0(忽略空白字符)。

@NotBlank

验证字符串不为null且至少包含一个非空白字符(如" "会校验失败)。

示例:

public class User {

    @NotNull(message = "ID不能为空")

    private Long id;

    @NotEmpty(message = "姓名不能为空")

    private String name;

    @NotBlank(message = "用户名不能为空")

private String username;

}

2. 数值校验

注解

作用

@Min(value)

验证数值(包括基本类型和包装类)必须大于或等于指定最小值。

@Max(value)

验证数值必须小于或等于指定最大值。

@DecimalMin(value)

验证 BigDecimal 或字符串表示的数值必须大于或等于指定值(支持精确小数)。

@DecimalMax(value)

验证 BigDecimal 或字符串表示的数值必须小于或等于指定值(支持精确小数)。

@Digits(integer=, fraction=)

验证数值的整数部分和小数部分的位数是否符合要求。

@Positive

验证数值必须为正数(不包括 0)。

@PositiveOrZero

验证数值必须为正数或 0。

@Negative

验证数值必须为负数(不包括 0)。

@NegativeOrZero

验证数值必须为负数或 0。

示例:

public class Product {

    @Min(value = 1, message = "价格不能低于1")

    private double price;

    @DecimalMax(value = "1000.00", message = "价格不能超过1000")

    private BigDecimal maxPrice;

    @Digits(integer = 3, fraction = 2, message = "折扣必须为最多3位整数和2位小数")

private double discount;

}

3. 长度 / 大小校验

注解

作用

@Size(min=, max=)

验证字符串、集合、数组、Map 等的长度或大小必须在指定范围内。

@Length(min=, max=)

验证字符串长度必须在指定范围内(常用于 Hibernate Validator)。

示例:

public class User {

    @Size(min = 6, max = 20, message = "密码长度必须在6-20位之间")

    private String password;

    @Size(max = 5, message = "爱好不能超过5个")

private List<String> hobbies;

}

4. 格式校验

注解

作用

@Email

验证字符串是否为合法的邮箱格式(默认正则较宽松,可通过regexp参数自定义)。

@Pattern(regexp=)

验证字符串是否符合指定的正则表达式。

@URL

验证字符串是否为合法的 URL 格式。

示例:

public class Contact {

    @Email(message = "邮箱格式不正确")

    private String email;

    @Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")

    private String phone;

    @URL(message = "网址格式不正确")

private String website;

}

二、高级校验注解

1. 日期 / 时间校验

注解

作用

@Past

验证日期 / 时间必须是过去的时间(如.util.Date、LocalDate等)。

@PastOrPresent

验证日期 / 时间必须是过去或当前时间。

@Future

验证日期 / 时间必须是未来的时间。

@FutureOrPresent

验证日期 / 时间必须是未来或当前时间。

示例:

public class Event {

    @Past(message = "创建时间必须是过去的时间")

    private LocalDateTime createTime;

    @Future(message = "活动开始时间必须是未来的时间")

private LocalDate startTime;

}

2. 条件校验

注解

作用

@AssertTrue

验证布尔值必须为true。

@AssertFalse

验证布尔值必须为false。

示例:

public class Agreement {

    @AssertTrue(message = "必须同意用户协议")

private boolean agreed;

}

3. 自定义校验

当内置注解无法满足需求时,可以通过@Constraint自定义校验注解:

// 自定义注解

@Target({ElementType.FIELD, ElementType.PARAMETER})

@Retention(RetentionPolicy.RUNTIME)

@Constraint(validatedBy = PasswordValidator.class)public 

@interface ValidPassword {

    String message() default "密码必须包含大小写字母和数字,长度8-20位";

    Class<?>[] groups() default {};

Class<? extends Payload>[] payload() default {};

}

// 校验器实现

public class PasswordValidator implements ConstraintValidator<ValidPassword, String> {

    private static final Pattern PASSWORD_PATTERN = 

        Pattern.compile("^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).{8,20}$");

    @Override

    public boolean isValid(String password, ConstraintValidatorContext context) {

        return password != null && PASSWORD_PATTERN.matcher(password).matches();

}

}

三、分组校验与级联校验

1. 分组校验

通过定义分组接口,为不同场景(如创建、更新)应用不同的校验规则:

// 定义分组接口

public interface CreateGroup {}

public interface UpdateGroup {}

// 实体类中指定分组

public class User {

    @NotNull(groups = UpdateGroup.class) // 更新时ID不能为空

    private Long id;

    @NotBlank(groups = {CreateGroup.class, UpdateGroup.class}) // 创建和更新时都需要

private String username;

}

// 控制器方法中指定分组

@PostMappingpublic User createUser(@Validated(CreateGroup.class) @RequestBody User user) {

return userService.createUser(user);

}

2. 级联校验

当对象包含嵌套属性时,使用@Valid触发嵌套校验:

public class Order {

    @NotNull

    private Long id;

    @Valid // 触发嵌套校验

    @NotNull

private User user;

}

四、Hibernate Validator 扩展注解

Hibernate Validator 是 JSR 规范的常用实现,提供了一些额外的校验注解:

注解

作用

@CreditCardNumber

验证字符串是否为合法的信用卡号(通过 Luhn 算法校验)。

@Currency

验证货币金额是否符合指定的货币代码(如@Currency("CNY"))。

@EAN

验证字符串是否为合法的商品条形码(如 EAN-13)。

@ISBN

验证字符串是否为合法的 ISBN 编号。

@Range(min=, max=)

验证数值是否在指定范围内(类似于@Min+@Max)。

示例:

public class Payment {

    @CreditCardNumber(message = "信用卡号格式不正确")

    private String cardNumber;

    @Range(min = 1, max = 12, message = "月份必须在1-12之间")

private int month;

}

五、使用注意事项

依赖引入:确保项目中包含spring-boot-starter-validation依赖:

<dependency>

    <groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-validation</artifactId>

</dependency>

全局异常处理:添加全局异常处理器捕获校验失败异常:

@ExceptionHandler(MethodArgumentNotValidException.class)public ResponseEntity<Map<String, String>> handleValidationExceptions(

        MethodArgumentNotValidException ex) {

// 处理校验错误

}

国际化支持:校验错误信息可通过message.properties实现国际化。

http://www.xdnf.cn/news/6189.html

相关文章:

  • 【springcloud学习(dalston.sr1)】Ribbon负载均衡(七)
  • 【行为型之模板方法模式】游戏开发实战——Unity标准化流程与可扩展架构的核心实现
  • 数据库MySQL学习——day10()
  • FFMPEG 与 mp4
  • elpis-core: 基于 Koa 实现 web 服务引擎架构设计解析
  • LeetCode 热题 100_颜色分类(98_75_中等_C++)(技巧)(计数;双指针)
  • git push 报错:send-pack: unexpected disconnect while reading sideband packet
  • 鸿蒙OSUniApp 开发的下拉刷新与上拉加载列表#三方框架 #Uniapp
  • “堆”和“栈”
  • matlab插值方法(简短)
  • 4G物联网模块实现废气处理全流程数据可视化监控配置
  • Android多媒体——媒体解码流程分析(十四)
  • Cursor 0.5版本发布,新功能介绍
  • 从零实现一个高并发内存池 - 2
  • WebGL知识框架
  • 网络协议分析 实验五 UDP-IPv6-DNS
  • openfeign与dubbo调用下载excel实践
  • Python知识框架
  • Idea 设置编码UTF-8 Idea中 .properties 配置文件中文乱码
  • 【大模型】OpenManus 项目深度解析:构建通用 AI Agent的开源框架
  • Ubuntu——执行echo $USE什么都不显示
  • Turborepo + Vite + Next.js + Shadcn Monorepo 项目构建
  • 【JVS更新日志】企业文档AI助手上线、低代码、智能BI、智能APS、AI助手5.14更新说明!
  • Python如何解决中文乱码
  • 驾驭数据洪流:大数据治理的全面解析与实战方案
  • git使用的DLL错误
  • 线性规划求解及演示
  • 项目基于udp通信的聊天室
  • CPU的用户态(用户模式)和核心态(内核态)
  • 若依框架页面