Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring validation vs Hibernate validation using annotation

i am creating a demo application using spring mvc 3.0.I have to apply the validation over the screen.I searches on the net and found that there is mainly 2 types of validation are used with the application :-

  1. Spring validations using validations Api
  2. Hibernate validation using hibernate validations

Hopefully somebody give me the suggestion which one is good one to implement in the application.

like image 477
Anshul Avatar asked Dec 22 '11 07:12

Anshul


1 Answers

I used both - I like the Hibernate Validation more - pretty easy to implement and pretty standard. It is automatically enabled when you have an implementation on the classpath. Here is an example:

@EmailValidator
@NotBlank
@Length(max=65)
private String email; 

Where does the message Error String comes from? In WEB-INF you must have a file called messages.properties :

NotBlank.ForgotPasswordBackingObject.email=Email address must be present

There is a standard @Email annotation, but an email such as : me@mycompany is considered valid, that is why I had to make my own @EmailValidator(changed a regex flag from * to + in the standard implementation). There are some issues that I came across : the order of validation - which validation you want to happen first, this is done with Validation groups, but this are not possible with the @Valid annotation, for example :

@RequestMapping(method=RequestMethod.POST, value="/auth/changePassword")
public ModelAndView submitChangePasswordPage(@Valid @ModelAttribute("ChangePasswordBackingObject") ChangePasswordBackingObject backingObject, BindingResult result, Principal principal)

That is why if you have your Controller in this form (in Spring MVC for example), then you have to simulate your logic in a way - I've done that also.

Another cool thing that you can do it to Validate two or more fields at at time (which I found pretty useful):

@FieldMatch.List({
    @FieldMatch(firstValue = "password" , secondValue = "confirmPassword")
})
public class RequestAccountBackingObject implements Serializable {
    private String password;
    private String confirmPassword;

And the implementation :

@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = FieldMatchImpl.class)
@Documented
public @interface FieldMatch{
    String message() default "{com.errorMessage}";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
    String firstValue();
    String secondValue();
    @Target({TYPE, ANNOTATION_TYPE})
    @Retention(RUNTIME)
    @Documented
    @interface List
    { FieldMatch[] value(); }
}

The other FieldMatchImpl would be :

public class FieldMatchImpl implements ConstraintValidator<FieldMatch, Object>{
    private String firstFieldName;
    private String secondFieldName;

and you need two methods implemented:

public void initialize(final FieldMatch constraintAnnotation){
    firstFieldName = constraintAnnotation.firstValue();
    secondFieldName = constraintAnnotation.secondValue();

Also:

public boolean isValid(final Object value, final ConstraintValidatorContext context){

    final String firstObj = BeanUtils.getProperty(value, firstFieldName);
    final String secondObj = BeanUtils.getProperty(value, secondFieldName);

Using org.apache.commons.beanutils.BeanUtils you can now validate the two fields.

Like this:

boolean result = firstObj.equals(secondObj);
if(!result) {
    context.disableDefaultConstraintViolation();
    context.buildConstraintViolationWithTemplate(errorMessage).addNode(firstFieldName).addConstraintViolation();
}

Other then that it has been a pleasure using the Hibernate Validation so far.

like image 165
Eugene Avatar answered Nov 15 '22 21:11

Eugene