【问题标题】:Using JSR-303 validator instead of Spring Validator使用 JSR-303 验证器代替 Spring 验证器
【发布时间】:2012-07-07 20:16:20
【问题描述】:

我在这里有一个非常幼稚的概念性问题需要澄清。在我的应用程序中,我目前使用 JSR 303 Hibernate Validator 来验证带有 @NotBlank 和 @NotNull 注释的域模型,例如检查用户名、密码等。

public class Admin {

  private Long id;
  @NotBlank(message = "Username should not be null")
  private String username;
  @NotBlank(message = "Username should not be null")
  private String password;
  ...

但是为了验证现有用户名之类的域逻辑,我仍然使用 Spring 的 Validator 接口

@Component
public class AdminValidator implements Validator {
  ...
  @Override
  public void validate(Object target, Errors errors) {
    Admin admin = (Admin) target;
    if (usernameAlradyExist())){
        errors.rejectValue("username", null, "This user already exist's in the system.");
    }

}

在控制器中我同时使用了两个

@RequestMapping(value = "/register", method = RequestMethod.POST)
public String register(@Valid @ModelAttribute("admin") Admin admin, BindingResult bindingResult,) {
    validator.validate(admin, bindingResult);
    if (bindingResult.hasErrors()) {
        return REGISTER_ADMIN.getViewName();

    }

是否可以只使用 Hibernate Validator 而根本不使用 Spring Validator 来验证域逻辑?

【问题讨论】:

    标签: spring spring-mvc


    【解决方案1】:

    是的,您可以将 JSR 验证用于域逻辑验证。您需要定义自定义约束注释并在其中定义域逻辑验证。
    喜欢
    定义自定义约束注解UserExistsConstraint

    @Target({ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Constraint(validatedBy=UserExistsConstraintValidator.class)
    
    public @interface UserExistsConstraint {
     String message() default "This user already exist's in the system.";
     Class<!--?-->[] groups() default {};
     Class<!--? extends Payload-->[] payload() default {};
    }   
    

    为自定义注释定义验证器。

    public class UserExistsConstraintValidator implements ConstraintValidator<UserExistsConstraint, object=""> {
    
     @Override
     public void initialize(UserExistsConstraint constraint) {
    
     }
    
     @Override
     public boolean isValid(Object target, ConstraintValidatorContext context) {
       if (usernameAlradyExist())
       {    
         return false;
       }
       else
       {
         return true; 
       }    
     }
    }
    

    使用自定义注解

    public class Admin {
    
      private Long id;
      @NotBlank(message = "Username should not be null")
      @UserExistsConstraint
      private String username;
      @NotBlank(message = "Username should not be null")
      private String password;
      ...
    

    【讨论】:

    • 谢谢,这就是我要找的 :-)
    • @tintin: 很高兴我能帮上忙 :)
    【解决方案2】:

    如果您使用 &lt;mvc:annotation-driven/&gt; 配置 Spring MVC,那么如果类路径中存在一些 JSR 303 验证器 impl(例如 hibernate-validator),它将自动配置 JSR 303 validator

    或者如果你明确想要配置验证器,你可以这样做:

    <bean id="validator"
          class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean"/>
    

    这将再次寻找 JSR 303 实现并将其用作验证器。

    您可以通过这种方式注册一个全局验证器来默认验证任何@Valid 表单对象:

    <mvc:annotation-driven validator="validator"/>
    

    【讨论】:

    • 我认为 OP 要求如何在 JSR 中实现业务逻辑验证,就像我们在 Spring 验证中定义的那样。恕我直言,它是关于在 JSR-303 中定义自定义注释,而您的答案是关于配置和使用 JSR 验证。如果我做出任何错误的假设,请纠正我。
    猜你喜欢
    • 2018-08-15
    • 2013-11-23
    • 2013-12-27
    • 2011-07-24
    • 1970-01-01
    • 1970-01-01
    • 2012-02-08
    • 2018-08-24
    • 2015-01-10
    相关资源
    最近更新 更多