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

使用spring-boot-starter-validation常用注释优雅判断类型

Spring Boot Validation 注解完全指南

概述

Spring Boot Validation 是基于 Jakarta Bean Validation 规范(JSR 380)的实现,提供了强大的数据校验功能。通过简单的注解,我们可以对方法参数、返回值、Bean属性等进行验证,确保数据的完整性和正确性。

依赖配置

pom.xml 中添加依赖:

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId>
</dependency>

核心注解详解

1. 空值校验注解

@NotNull

作用:验证字段值不为 null
适用类型:任何类型
示例

@NotNull(message = "用户ID不能为空")
private String userId;
@NotBlank

作用:验证字符串不为 null 且长度大于0(去除前后空白)
适用类型:String
示例

@NotBlank(message = "用户名不能为空")
private String userName;
@NotEmpty

作用:验证字段不为 null 且不为空(集合/数组长度>0,字符串长度>0)
适用类型:String、Collection、Map、Array
示例

@NotEmpty(message = "角色列表不能为空")
private List<String> roles;

2. 长度校验注解

@Size

作用:验证字符串、集合或数组的长度在指定范围内
参数

  • min:最小长度
  • max:最大长度
  • message:错误消息

示例

@Size(min = 3, max = 20, message = "用户名长度必须在3-20个字符之间")
private String userName;@Size(max = 200, message = "描述长度不能超过200个字符")
private String description;

3. 数值范围校验注解

@Min

作用:验证数字字段的最小值
示例

@Min(value = 1, message = "页码不能小于1")
private Integer page;
@Max

作用:验证数字字段的最大值
示例

@Max(value = 100, message = "每页大小不能大于100")
private Integer size;
@DecimalMin

作用:验证数字字段的最小值(支持字符串格式)
示例

@DecimalMin(value = "0.0", inclusive = false, message = "价格必须大于0")
private BigDecimal price;
@DecimalMax

作用:验证数字字段的最大值(支持字符串格式)
示例

@DecimalMax(value = "10000.0", message = "价格不能超过10000")
private BigDecimal price;

4. 格式校验注解

@Email

作用:验证字段值是否符合邮箱格式
示例

@Email(message = "邮箱格式不正确")
private String email;
@Pattern

作用:使用正则表达式验证字段值格式
示例

@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")
private String phone;
常用正则表达式模式:
  • 手机号:^1[3-9]\\d{9}$
  • 身份证:^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$
  • 邮编:^[1-9]\\d{5}$

5. 布尔校验注解

@AssertTrue

作用:验证布尔字段值为 true
示例

@AssertTrue(message = "必须同意协议")
private Boolean agreed;
@AssertFalse

作用:验证布尔字段值为 false
示例

@AssertFalse(message = "不能是测试用户")
private Boolean isTest;

6. 日期时间校验注解

@Past

作用:验证日期时间字段是过去时间
示例

@Past(message = "生日必须是过去时间")
private LocalDate birthday;
@PastOrPresent

作用:验证日期时间字段是过去或现在时间
示例

@PastOrPresent(message = "创建时间不能是未来时间")
private LocalDateTime createTime;
@Future

作用:验证日期时间字段是未来时间
示例

@Future(message = "过期时间必须是未来时间")
private LocalDateTime expireTime;
@FutureOrPresent

作用:验证日期时间字段是未来或现在时间
示例

@FutureOrPresent(message = "计划时间不能是过去时间")
private LocalDateTime planTime;

7. 复杂对象校验注解

@Valid

作用:级联验证,验证嵌套对象
示例

@Valid
@NotNull(message = "用户信息不能为空")
private UserInfo userInfo;

分组校验

创建校验分组

public interface CreateGroup {}
public interface UpdateGroup {}

使用分组校验

@NotBlank(groups = CreateGroup.class, message = "用户名不能为空")
private String userName;@NotNull(groups = UpdateGroup.class, message = "用户ID不能为空")
private Long id;

控制器中使用分组

@PostMapping("/create")
public R<User> createUser(@Validated(CreateGroup.class) @RequestBody User user) {// 业务逻辑
}@PutMapping("/update")
public R<User> updateUser(@Validated(UpdateGroup.class) @RequestBody User user) {// 业务逻辑
}

自定义校验注解

1. 创建自定义注解

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneValidator.class)
public @interface Phone {String message() default "手机号格式不正确";Class<?>[] groups() default {};Class<? extends Payload>[] payload() default {};
}

2. 实现校验逻辑

public class PhoneValidator implements ConstraintValidator<Phone, String> {private static final Pattern PHONE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");@Overridepublic boolean isValid(String value, ConstraintValidatorContext context) {if (value == null) {return true; // 使用@NotNull处理空值}return PHONE_PATTERN.matcher(value).matches();}
}

3. 使用自定义注解

@Phone(message = "手机号格式不正确")
private String phone;

控制器中使用验证

基本用法

@PostMapping("/login")
public R<LoginToken> login(@Valid @RequestBody LoginRequest request) {return authService.login(request);
}

获取校验错误信息

@PostMapping("/register")
public R<User> register(@Valid @RequestBody User user, BindingResult result) {if (result.hasErrors()) {// 处理校验错误List<FieldError> errors = result.getFieldErrors();String errorMessage = errors.stream().map(error -> error.getField() + ": " + error.getDefaultMessage()).collect(Collectors.joining(", "));return R.fail(errorMessage);}// 业务逻辑
}

全局异常处理

@RestControllerAdvice
public class GlobalExceptionHandler {@ExceptionHandler(MethodArgumentNotValidException.class)public R<Object> handleValidationException(MethodArgumentNotValidException ex) {List<FieldError> errors = ex.getBindingResult().getFieldErrors();Map<String, String> errorMap = new HashMap<>();for (FieldError error : errors) {errorMap.put(error.getField(), error.getDefaultMessage());}return R.fail("参数校验失败").data(errorMap);}
}

实战示例

用户注册DTO

@Data
public class RegisterRequest {@NotBlank(message = "用户名不能为空")@Size(min = 3, max = 20, message = "用户名长度3-20字符")private String username;@NotBlank(message = "密码不能为空")@Size(min = 6, max = 20, message = "密码长度6-20字符")private String password;@Email(message = "邮箱格式不正确")private String email;@Pattern(regexp = "^1[3-9]\\d{9}$", message = "手机号格式不正确")private String phone;@Min(value = 18, message = "年龄必须大于18岁")@Max(value = 100, message = "年龄必须小于100岁")private Integer age;@AssertTrue(message = "必须同意用户协议")private Boolean agreed;
}

商品信息DTO

@Data
public class ProductDto {@NotBlank(message = "商品名称不能为空")@Size(max = 100, message = "商品名称不能超过100字符")private String name;@DecimalMin(value = "0.0", inclusive = false, message = "价格必须大于0")@DecimalMax(value = "999999.99", message = "价格不能超过999999.99")private BigDecimal price;@Min(value = 0, message = "库存不能为负数")private Integer stock;@Future(message = "过期时间必须是未来时间")private LocalDateTime expireDate;@Valid@NotNull(message = "分类信息不能为空")private Category category;
}

最佳实践

1. 合理的错误消息

  • 提供具体、明确的错误消息
  • 避免技术术语,使用用户友好的语言
  • 包含具体的约束信息

2. 校验顺序

@NotBlank(message = "不能为空")
@Size(min = 6, max = 20, message = "长度6-20字符")
@Pattern(regexp = "^(?=.*[a-z])(?=.*[A-Z])(?=.*\\d).+$", message = "必须包含大小写字母和数字")
private String password;

3. 性能考虑

  • 避免复杂的正则表达式
  • 对于频繁调用的接口,考虑缓存校验结果
  • 使用分组校验减少不必要的验证

4. 安全性

  • 不要依赖前端验证,后端必须进行验证
  • 对敏感数据使用额外的安全验证
  • 验证输入数据的范围和格式,防止注入攻击

常见问题排查

1. 验证不生效

  • 检查是否添加了 @Valid@Validated 注解
  • 确认依赖已正确添加
  • 检查控制器方法参数是否正确

2. 错误消息不显示

  • 检查是否有全局异常处理
  • 确认消息模板配置正确

3. 自定义注解不工作

  • 检查 ConstraintValidator 实现是否正确
  • 确认注解元数据配置正确

总结

Spring Boot Validation 提供了强大而灵活的数据验证机制,通过合理的注解组合可以满足大多数业务场景的验证需求。掌握这些注解的用法,可以显著提高代码质量和系统安全性。

注解类型主要注解适用场景
空值校验@NotNull, @NotBlank, @NotEmpty必填字段验证
长度校验@Size字符串、集合长度限制
数值校验@Min, @Max, @DecimalMin, @DecimalMax数值范围限制
格式校验@Email, @Pattern数据格式验证
布尔校验@AssertTrue, @AssertFalse布尔值验证
日期校验@Past, @Future 等时间验证
级联校验@Valid嵌套对象验证

通过合理运用这些注解,可以构建出健壮、安全的Spring Boot应用程序。

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

相关文章:

  • 小迪安全v2023学习笔记(七十六讲)—— Fuzz模糊测试口令爆破目录爆破参数爆破Payload爆破
  • uniapp 开发上架 iOS App全流程
  • uni-app iOS 文件管理与 itools 配合实战,多工具协作的完整流程
  • 如何选择适合企业的海外智能客服系统:6 大核心维度 + 实战选型指南
  • 集成运算放大器的作用、选型和测量指南-超简单解读
  • 4 款音分轨工具推荐:制片帮领衔,轻松搞定音频分离
  • 实现信号的小波分解和重构
  • 7.5el-tree 组件详解
  • 创建消息队列,完成信息传输
  • MySQL索引分类
  • 英语四级学习指南
  • A*(Astar)算法详解与应用
  • 电池分选机的自动化解决方案|深圳比斯特
  • SQLAlchemy ORM 入门教程
  • 马斯克砸钱造AI,却败给最low的“让离职员工轻松拷走代码”
  • MyHeyGen-开源版HeyGen,视频翻译工具
  • 平衡车 - 电机调速
  • HI3516CV610-00S 海思HI3516CV610安防高清视频编解码方案提供开发板
  • Nature Machine Intelligence 基于强化学习的磁性微型机器人自主三维位置控制
  • 物联网能源管控平台建设方案
  • 概率质量/密度函数、累计分布函数详解
  • github存储代码(上传更新删除)--实操版
  • 需求调研与分析
  • 最佳红米手机数据擦除软件
  • 场景题:如果一个大型项目,某一个时间所有的CPU的已经被占用了,导致服务不可用,我们开发人员应该如何使服务器尽快恢复正常
  • 2025年家装设计软件推荐:告别选择困难,轻松打造梦想之家
  • C++的内存和数组的申请释放
  • 对数似然比(LLR)
  • C/C++ 中的inline(内联函数关键字)详解
  • 功能持续优化,应用商店新增CRM分类,1Panel v2.0.10版本正式发布