当使用 @Validated、@GroupSequence 和自定义校验规则时,可以实现对实体类属性的分组校验
首先,定义验证分组的接口:
public interface Group1 {} public interface Group2 {} @GroupSequence({Group1.class, Group2.class}) public interface MyValidationGroupSequence {}
然后,创建一个实体类,并应用验证分组的约束和自定义校验规则:
public class User { @NotBlank(groups = Group1.class) private String username; @Size(min = 6, max = 20, groups = Group2.class) @CustomValidation(groups = Group2.class) private String password; // 省略构造函数、getter 和 setter 方法 }
在上述示例中,User 类应用了不同分组的约束。username 字段在 Group1 分组中不能为空白(@NotBlank),password 字段在 Group2 分组中必须是长度在 6 到 20 之间的字符串,并通过 @CustomValidation 标记了自定义校验规则。
接下来,定义一个自定义校验注解和校验器:
@Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = CustomValidator.class) public @interface CustomValidation { String message() default "Invalid value"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; } public class CustomValidator implements ConstraintValidator<CustomValidation, String> { public boolean isValid(String value, ConstraintValidatorContext context) { return value.matches("[A-Za-z0-9]+"); } }
在上述示例中,定义了一个名为 CustomValidation 的自定义校验注解,并将它应用在 password 字段上。同时,实现了 CustomValidator 类,对属性值进行自定义校验。
最后,创建一个服务类,并在方法参数上应用 @Validated 和验证分组注解进行校验:
@Service @Validated public class UserService { public void createUser(@Validated(MyValidationGroupSequence.class) User user) { // 创建用户的业务逻辑 } }
在上述示例中,createUser 方法使用了 @Validated 注解来启用方法参数校验,并通过 @Validated(MyValidationGroupSequence.class) 指定了要验证的分组。
使用该服务类进行方法调用时,会按照 @GroupSequence 中指定的顺序依次对分组进行校验,并执行自定义校验规则。
注意,为了使自定义校验规则生效,需要在 Spring 配置文件(如配置类)中配置自定义校验器,当然springboot环境已经自动注入了:
@Configuration public class AppConfig { @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { return new MethodValidationPostProcessor(); } }
以上展示了结合 @Validated、@GroupSequence 和自定义校验规则的用法,以实现分组校验和自定义校验逻辑。具体的验证逻辑和业务约束根据实际需求进行定义和实现。
MethodValidationPostProcessor作用
MethodValidationPostProcessor 是 Spring 提供的一个后置处理器,用于在方法调用时对方法参数进行校验。
当将 MethodValidationPostProcessor 添加到 Spring 容器中时,它会自动拦截标注了 @Validated 注解的方法,并在方法调用之前执行参数校验操作。如果方法参数不满足验证约束,则抛出 MethodArgumentNotValidException 异常或 ConstraintViolationException 异常。
使用 MethodValidationPostProcessor 可以方便地在方法级别上实现参数校验,而无需显式调用 Validator 对象进行验证。
在示例中,通过在配置类中定义 MethodValidationPostProcessor 的 bean,将其添加到 Spring 容器中:
@Configuration public class AppConfig { @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { return new MethodValidationPostProcessor(); } }
这样,在使用 @Validated 注解标注的方法中,就可以触发方法参数的校验。例如,在 UserService 中的 createUser 方法上使用 @Validated 注解:
@Service @Validated public class UserService { public void createUser(@Validated(MyValidationGroupSequence.class) User user) { // 创建用户的业务逻辑 }
}
当调用 createUser 方法时,MethodValidationPostProcessor 会拦截该方法的调用,根据 @Validated 注解和指定的验证分组(MyValidationGroupSequence.class),对 User 对象的属性进行校验。如果校验失败,则会抛出相应的异常。
总而言之,MethodValidationPostProcessor 是一个后置处理器,用于实现方法参数的校验。它简化了在方法层面进行验证的操作,提供了方便的验证机制。
显示调用
如果你不想使用 MethodValidationPostProcessor,而是显式调用 Validator 对象进行验证,可以按照以下步骤进行编写:
首先,需要注入一个 Validator 对象到你的类中。可以使用 LocalValidatorFactoryBean 或者 Validator 接口的其他实现类。
@Autowired private Validator validator;
接下来,在方法中手动调用 validator.validate() 方法进行参数校验。假设你的方法名为 createUser,接收 User 对象作为参数。
public void createUser(User user) { Set<ConstraintViolation<User>> violations = validator.validate(user, MyValidationGroupSequence.class); if (!violations.isEmpty()) { // 处理校验失败的情况 for (ConstraintViolation<User> violation : violations) { System.out.println(violation.getMessage()); } } // 创建业务逻辑 }
上述示例中,validator.validate() 方法接受两个参数:要校验的对象 user 和验证分组 MyValidationGroupSequence.class。它会返回一个包含所有校验失败信息的 Set<ConstraintViolation> 集合。
如果集合不为空,说明存在校验失败的情况。可以通过遍历集合中的 ConstraintViolation 对象,获取具体的校验错误信息进行处理。
注意,在使用显式调用 Validator 对象进行验证时,需要自己处理校验失败的情况,并根据实际需求进行后续操作。
最后,确保你已经在 Spring 配置文件(如配置类)中配置了 Validator 的 bean。
@Bean public Validator validator() { LocalValidatorFactoryBean factoryBean = new LocalValidatorFactoryBean(); factoryBean.setProviderClass(HibernateValidator.class); factoryBean.afterPropertiesSet(); return factoryBean.getValidator(); }
当然也可以直接使用工厂模式的对象进项校验:
public class Main { public static void main(String[] args) { ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator(); User user = new User(); Set<ConstraintViolation<User>> violations = validator.validate(user, MyValidationGroupSequence.class); for (ConstraintViolation<User> violation : violations) { System.out.println(violation.getMessage()); } } }
以上就是使用显式调用 Validator 对象进行参数验证的方法。通过手动调用 validator.validate() 方法,可以实现对对象的参数校验,并且可以通过检查 ConstraintViolation 集合来处理校验失败的情况。