手动调用带@Valid参数和Errors入参的校验方法如何获取对应Errors对象
方案1:方法内部自行生成绑定对应对象的Errors(推荐)
直接去掉方法的Errors入参,在方法内部初始化和当前入参T user绑定的空Errors对象,再主动触发JSR-380校验规则写入校验结果,从根源上保证Errors和@Valid修饰的对象完全匹配,不需要外部传参,完全规避传错的可能。
代码示例:
// 类中先注入Spring校验器 @Autowired private org.springframework.validation.Validator validator; public <T> T validate(PasswordEncoder encoder , @Valid T user) { // 初始化仅绑定当前user的空Errors对象 Errors errors = new BeanPropertyBindingResult(user, user.getClass().getSimpleName()); // 触发@Valid对应的校验规则,结果写入errors validator.validate(user, errors); this.statusMsg = errors.getAllErrors().stream() .collect(Collectors.toMap(ObjectError::getObjectName, ObjectError::getDefaultMessage)); // 原有业务逻辑不变 if(user.getClass() == EnterpriseContainer.class) { } else if(user.getClass() == UserContainer.class) { } return null; }
方案2:泛型包装类绑定校验对象和Errors(适合需要外部传入Errors的场景)
如果你的业务逻辑要求必须从外部传入Errors(比如需要提前写入自定义错误),可以定义泛型包装类强制绑定对象和对应的Errors,编译器会自动校验泛型匹配,避免传错。
第一步:定义绑定类
public class ValidBinding<T> { private final T target; private final Errors errors; private ValidBinding(T target, Errors errors) { // 构造时强制校验Errors和对象匹配 if (!errors.getObjectName().equals(target.getClass().getSimpleName())) { throw new IllegalArgumentException("Errors与目标对象不匹配"); } this.target = target; this.errors = errors; } // 静态工厂方法生成绑定实例 public static <T> ValidBinding<T> of(T target) { return new ValidBinding<>(target, new BeanPropertyBindingResult(target, target.getClass().getSimpleName())); } public T getTarget() { return target; } public Errors getErrors() { return errors; } }
第二步:改造原有校验方法入参
public <T> T validate(PasswordEncoder encoder, @Valid ValidBinding<T> binding) { T user = binding.getTarget(); Errors errors = binding.getErrors(); // 原有业务逻辑不变 this.statusMsg = errors.getAllErrors().stream() .collect(Collectors.toMap(ObjectError::getObjectName, ObjectError::getDefaultMessage)); if(user.getClass() == EnterpriseContainer.class) { } else if(user.getClass() == UserContainer.class) { } return null; }
调用时只能通过ValidBinding.of(user)生成实例,编译器会强制校验泛型匹配,保证Errors一定是对应@Valid修饰的T对象的绑定结果。
内容的提问来源于stack exchange,提问作者Drago Ban
相关产品推荐
相关产品推荐

