Search code examples
validationgwthibernate-validator

GWT JSR303 Validation, validate method OR use custom annotations


I'm trying to use GWT's 2.5 in-build validation feature. I have a few complex validations. Cross field validation with Hibernate Validator (JSR 303) suggests that I could either include methods which do the validation OR write my own annotations. However, both don't work.

public class PageData extends Serializable
    @NotNull(message="Cannot be null!")
    Boolean value

    @AssertTrue(message="isValid() is false!")
    private boolean isValid() {
        return false;
    }

    //Getters and Setters
}

Boolean value is validated. However, isValid() is never called/validated. But why? Is this a GWt specific problem?

Then I tried to write my own annotation, The @FieldMatch example in Cross field validation with Hibernate Validator (JSR 303) uses Beans.getProperty() from Apache Commons BeanUtils, which I cannot use in GWT. Is there any way to make these kind of complex annotations work in GWT?


Solution

  • Here is how I created a custom validation that works across multiple fields of one bean. It checks that when the field ContactProfile for a Contact bean is set to COMPANY, then company name must be filled out, otherwise when set to PERSON, the first name or last name must be filled out :

    Annotation definition :

    @Target({ ElementType.TYPE })
    @Retention(RetentionPolicy.RUNTIME)
    @Constraint(validatedBy = ValidCompanyOrPersonValidator.class)
    public @interface ValidCompanyOrPerson {
    
        String message() default "{contact.validcompanyorperson}";
    
        Class<?>[] groups() default {};
    
        Class<? extends Contact>[] payload() default {};
    }
    

    Implementation :

    public class ValidCompanyOrPersonValidator implements ConstraintValidator<ValidCompanyOrPerson, Contact> {
    
        ValidCompanyOrPerson annotation;
    
        public void initialize(ValidCompanyOrPerson annotation) {
            this.annotation = annotation;
        }
    
        @SuppressWarnings("nls")
        public boolean isValid(Contact contact, ConstraintValidatorContext context) {
            boolean ret = false;
            if (contact.getContactProfile() == null) {
            } else if (contact.getContactProfile().equals(ContactProfile.COMPANY)) {
                ret = (contact.getCompanyName() != null);
            } else if (contact.getContactProfile().equals(ContactProfile.PERSON)) {
                ret = (contact.getGivenName() != null || contact.getFamilyName() != null);
            }
            return ret;
        }
    }
    

    Now I can set

    @ValidCompanyOrPerson
    public class Contact  {
     ...
    }
    

    I can use this validation both client (GWT) and server side.

    Hope that helps ....