Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using JSR-303 validator instead of Spring Validator

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?

like image 572
tintin Avatar asked Jul 07 '12 20:07

tintin


People also ask

What is JSR-303 Bean Validation?

1 Overview of the JSR-303 Bean Validation API. JSR-303 standardizes validation constraint declaration and metadata for the Java platform. Using this API, you annotate domain model properties with declarative validation constraints and the runtime enforces them.

How do you use a JSR-303?

4.1 JSR-303 – Validate Request Body@Valid annotation in the method, will validate the Customer data model. In case of validation error system will send out an error message to the customer. Spring framework will create a Validator and this will be available for the data validation.

Which is the default Validator of Spring?

Spring MVC Framework supports JSR-303 specs by default and all we need is to add JSR-303 and it's implementation dependencies in Spring MVC application.

Is @valid and @validated the same?

The @Valid annotation ensures the validation of the whole object. Importantly, it performs the validation of the whole object graph. However, this creates issues for scenarios needing only partial validation. On the other hand, we can use @Validated for group validation, including the above partial validation.


2 Answers

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;
  ...
like image 100
Ajinkya Avatar answered Dec 06 '22 05:12

Ajinkya


If you are configuring Spring MVC with <mvc:annotation-driven/> then it will automatically configure a JSR 303 validator if some JSR 303 validator impl(hibernate-validator for eg) is present in the classpath.

Or if you explicitly want to configure the validator, you can do this:

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

This again would look for a JSR 303 implementation and use that as the validator.

You can default it to validate any @Valid form object by registering a global validator this way:

<mvc:annotation-driven validator="validator"/>
like image 22
Biju Kunjummen Avatar answered Dec 06 '22 03:12

Biju Kunjummen