Saturday, February 18, 2012

Creating custom annotation in JSR-303

I was trying JSR-303 bean validation to validate Spring bean. I found it really easy.
Hibernate Validator provides reference implementation of JSR-303.
It supports constraint annotations like

@AssertFalse
@AssertTrue
@CreditCardNumber
@Digits
@EAN
@Email
@Future
@Length
@Min
@Max
@NotNull
@NotEmpty 
 
It provides really good set of constraint annotation but I wanted to add a validation like
Field can be Null OR  It should contain a non empty string      
It means combination of two constraint annotation i.e. @Null OR @NotEmpty, But you cannot create combine annotation in OR way. So I ended up in writing custom constraint annotation.
To write a custom constraint, you need to
1. Write a annotation
2. Write a validator class for annotation

Here is my custom annotation @NotBlankOrNull.
@Documented
@Constraint(validatedBy = { NotBlankOrNullValidator.class })
@Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER })
@Retention(RUNTIME)
public @interface NotBlankOrNull {
    String message() default "{org.hibernate.validator.constraints.NotBlankOrNull.message}";

    Class[] groups() default { };

    Class[] payload() default { };
}

@Constraint defines class which will validate your constraint, it will provide business logic for your constraint. @Target defines program elements to which annotation can be applied. The attributes defines inside i.e message,groups,default will be used with annotation.
Here is my validator class

public class NotBlankOrNullValidator implements ConstraintValidator {

    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        if ( s == null ) {
            return true;
        }
        return s.trim().length() > 0;
    }

    @Override
    public void initialize(NotBlankOrNull constraint) {

    }
} 

The logic for constraint is defined inside isValid() method. I have checked if string is null or it is a non empty string ie length > 0.  Validation will be successful if isValid() returns true, if it returns false then error message will be displayed.   

That's it now you can use your custom annotation

public class BeanValidation {

@NotBlankOrNull(message="Invalid input value.") 
String input;

public String getInput() {
return input;
}

public void setInput(String input) {
this.input = input;
}
} 

You can define any type of business logic inside the validators isValid() method. This allow you to create any custom validation.  

 
~Ajinkya.


No comments:

Post a Comment