【问题标题】:@Valid with spring annotations@Valid 带有spring注解
【发布时间】:2014-07-25 00:33:43
【问题描述】:

我已经为我的项目启用了 spring mvc 注释驱动。这个想法是使用 @Valid 注释和 spring 注释来避免控制器中的行,如: validator.validate(form, errors)

我注意到这些东西不适用于包中的 spring 注释:

org.springmodules.validation.bean.conf.loader.annotation.handle

经过调查,我发现我可以使用 javaxorg.hibernate.validator.constraints 的注释作为替代方式。

但不幸的是,我有一些特殊情况无法做到这一点:

@MinSize(applyIf = "name NOT EQUALS 'default'", value = 1)

很高兴知道 spring 注释可以以何种方式与 @Valid 或任何其他替代方式一起使用以避免与 applyIf 属性相关的重构(将条件移动到 java 代码)。

【问题讨论】:

    标签: java spring validation


    【解决方案1】:

    这是一个如何创建自定义验证器的示例。

    首先创建自己的注解:

    @Target({ ElementType.METHOD, ElementType.FIELD })
    @Retention(RetentionPolicy.RUNTIME)
    @Constraint(validatedBy = StringValidator.class)
    public @interface ValidString {
    
        String message() default "Invalid data";
        int min() default -1;
        int max() default -1;
        String regex() default "";
    
        Class<?>[] groups() default {};
    
        Class<? extends Payload>[] payload() default {};
    }
    

    那么您将需要一个自定义验证器:

    public class StringValidator implements ConstraintValidator<ValidString, String> {
    
        private int              _min;
        private int              _max;
        private String           _regex;
        private boolean          _decode;
    
        public void initialize(ValidString constraintAnnotation) {
            _min = constraintAnnotation.min();
            _max = constraintAnnotation.max();
            _regex = constraintAnnotation.regex();
            _decode = constraintAnnotation.decode();
        }
    
        public boolean isValid(String value, ConstraintValidatorContext context) {
    
            if (value == null) {
                return false;
            }
    
            String test = value.trim();
    
            if (_min >= 0) {
                if (test.length() < _min) {
                    return false;
                }
            }
    
            if (_max > 0) {
                if (test.length() > _max) {
                    return false;
                }
            }
    
            if (_regex != null && !_regex.isEmpty()) {
                if (!test.matches(_regex)) {
                    return false;
                }
            }
    
            return true;
        }
    }
    

    最后你可以在你的 Beans 和 Controller 中使用它了:

    public class UserForm {
    
        @ValidString(min=4, max=20, regex="^[a-z0-9]+")
        private String name;
    
        //...
    }
    
    // Method from Controller
    @RequestMapping(method = RequestMethod.POST)
    public String saveUser(@Valid UserForm form, BindingResult brResult) {
    
        if (brResult.hasErrors()) {
            //TODO:
        }
    
        return "somepage";
    }
    

    【讨论】:

      【解决方案2】:

      这样的事情可能会帮助你

      public class UserValidator implements Validator {
      
          @Override
          public boolean supports(Class clazz) {
            return User.class.equals(clazz);
          }
      
          @Override
          public void validate(Object target, Errors errors) {
            User user = (User) target;
      
            if(user.getName() == null) {
                errors.rejectValue("name", "your_error_code");
            }
      
            // do "complex" validation here
      
          }
      
      }
      

      然后在您的控制器中,您将拥有:

      @RequestMapping(value="/user", method=RequestMethod.POST)
          public createUser(Model model, @ModelAttribute("user") User user, BindingResult result){
              UserValidator userValidator = new UserValidator();
              userValidator.validate(user, result);
      
              if (result.hasErrors()){
                // do something
              }
              else {
                // do something else
              }
      }
      

      如果有验证错误,result.hasErrors() 将为真。

      注意:您还可以在控制器的 @InitBinder 方法中设置验证器,使用 "binder.setValidator(...)" 。或者您可以在控制器的默认构造函数中实例化它。或者在控制器中注入 @Component/@ServiceUserValidator (@Autowired):非常有用,因为大多数验证器都是单例 + 单元测试模拟变得更容易 + 你的验证器可以调用其他 Spring 组件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-24
        • 2011-04-05
        • 2015-01-04
        相关资源
        最近更新 更多