点击上方"程序员蜗牛g",选择"设为星标"跟蜗牛哥一起,每天进步一点点
程序员蜗牛g大厂程序员一枚 跟蜗牛一起 每天进步一点点32篇原创内容**公众号
本篇文章将详细的介绍基于注解参数验证的9大技巧。
实战案例
2.1 基本注解
Spring Validation 提供了一组用于常见验证任务的标准如下示例:

在Controller接口参数上开启验证功能:

**
**
2.2 自定义注解验证
对于特定的业务规则,你可以创建自己的自定义验证约束。

**
**
typescript
public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String> { @Resource private UserRepository userRepository; @Override public boolean isValid(String username, ConstraintValidatorContext context) { if (username == null) { return true; // Let @NotNull handle null values } return !userRepository.existsByUsername(username); }}
2.3 分组验证
分组验证允许你针对不同场景应用不同的规则,例如创建操作与更新操作。如下示例(定义分组):

使用分组
less
public class ProductDTO { @Null(groups = ValidationGroups.Create.class, message = "创建商品时ID必须为空") @NotNull(groups = ValidationGroups.Update.class, message = "更新商品时商品ID不能为空") private Long id; @NotBlank(groups = {ValidationGroups.Create.class, ValidationGroups.Update.class}) private String name;}
分组验证

注意:使用 @Validated 注解,因为它是支持验证组的注解。@Valid 不支持。
2.4 嵌套验证
对于复杂对象,你可以验证嵌套对象和集合。

注意:使用 @Valid 注解需要级联验证的字段,以确保验证器深入检查嵌套对象。
2.5 方法级验证
你也可以直接对服务层方法进行验证,而不仅仅是对控制器参数进行验证。

如果你是在Controller方法上那么你 不需要 在类上使用@Validated注解。
2.6 错误消息国际化
当发生错误时我们可以通过2中方式来提示具体的错误消息。
-
直接指定错误消息
**
**
直接通过 message 指定要展示的错误消息。

- 使用占位符
message属性可以使用 {xxx} 语法,其中 xxx 为你在资源文件中定义的key。

接下来,新建 classpath:messages_zh_CN.properties 和 classpath:messages_en_US.properties 资源文件。
上面我们是使用的spring boot默认的basename,你可以自定义,通过 spring.messages.basename 属性配置。
2.7 编程验证
除了注解之外,你还可以手动触发验证。

适用于验证是有条件的复杂业务逻辑,或用于验证未通过控制器传递的对象。
2.8 组合验证
将多个基本约束组合成一个单一的、可复用的且更具表现力的注解。
less
@NotNull@Size(min = 8, max = 30)@Pattern(regexp = "^(?=.*[0-9])(?=.*[a-z])(?=.*[A-Z])(?=.*[@#$%^&+=]).*$", message = "密码必须包含至少一个数字、小写字母、大写字母和特殊字符")@Target({ElementType.FIELD, ElementType.PARAMETER})@Retention(RetentionPolicy.RUNTIME)@Constraint(validatedBy = {})public @interface StrongPassword {
String message() default "密码不符合安全要求"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {};}
使用组合注解

优点:提高代码可读性,并确保验证规则得到一致应用。
2.9 跨字段验证
根据字段与其他字段的关系来验证字段,例如确保 "确认密码" 字段与 "密码" 字段匹配。创建一个类级约束:

密码验证器
vbnet
public class PasswordMatchesValidator implements ConstraintValidator<PasswordMatches, Object> { private String field; private String fieldMatch; @Override public void initialize(PasswordMatches constraintAnnotation) { this.field = constraintAnnotation.field(); this.fieldMatch = constraintAnnotation.fieldMatch(); } @Override public boolean isValid(Object value, ConstraintValidatorContext context) { try { // 通过反射获取字段值 Field field1 = value.getClass().getDeclaredField(field); field1.setAccessible(true); Object fieldValue1 = field1.get(value); Field field2 = value.getClass().getDeclaredField(fieldMatch); field2.setAccessible(true); Object fieldValue2 = field2.get(value); // 比较两个字段值(处理null情况) if (fieldValue1 == null) { return fieldValue2 == null; } return fieldValue1.equals(fieldValue2); } catch (NoSuchFieldException | IllegalAccessException e) { throw new RuntimeException("Failed to validate password fields", e); } }}
使用注解

Controller接口
less
@PostMapping("/register")public ResponseEntity<?> register(@Valid @RequestBody UserRegistrationDTO dto, BindingResult result) { if (result.hasErrors()) { List<String> errors = result.getAllErrors() .stream() .map(err -> err.getDefaultMessage()) .toList() ; return ResponseEntity.badRequest().body(errors); } return ResponseEntity.ok("Registration successful");}

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、转发、在看。
关注公众号:woniuxgg,在公众号中回复:笔记 就可以获得蜗牛为你精心准备的java实战语雀笔记,回复面试、开发手册、有超赞的粉丝福利!