Spring – Using JSR-303 validator instead of Spring Validator

springspring-mvc

I have a very naive conceptual question here for clarification. In my app I'm currently using JSR 303 Hibernate Validator for validating the domain model with @NotBlank and @NotNull annotations, like checking username, password etc.

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;
  ...

But for validating the domain logic like existing username, I'm still using Spring's Validator interface

@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.");
    }

}

In the controller I'm using both

@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();

    }

Is it possible just to use Hibernate Validator and not at all use Spring Validator for validating domain logic?

Best Answer

Yes, You can use JSR validation for your domain logic validation. You need to define custom constraint annotations and define your domain logic validation inside it.
Like
Defining custom constraint annotation 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 {};
}   

Defining validator for custom annotation.

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; 
   }    
 }
}

Using custom annotation

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;
  ...
Related Topic