The goal of this paper is to setup quickly and smoothly a clean validation process on your DTO. It shows an easy setup using GIN and GWT-Dispatch. An Intro is also available here Gwt 2.5 Validation Intro
The needed libraires to start are: Javax validation (Api), Hibernate validators (Sources and Implementation) and Slf4j (logger).
For the next step we are going to build a custom annotation which will be use into our gwt-dispatch actions:
Here the code for custom validator and his annotation:
@Target({ ElementType.FIELD, ElementType.ANNOTATION_TYPE })
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Constraint(validatedBy = RequiredValidator.class)
public @interface Required {
String message() default "Value is required";
Class[] groups() default {};
Class[] payload() default {};
}
public class RequiredValidator implements ConstraintValidator {
@Override
public void initialize(Required constraintAnnotation) { }
@Override
public boolean isValid(String value, ConstraintValidatorContext context) {
return (!Strings.isNullOrEmpty(value));
// use Guava strings to check null or empty value
}
}
Now we can use our required annotation into our action (There is also a possibility to use more than one annotation on our field):
public class SendMailAction extends ActionImpl {
@Required
private String email;
...
private SendMailAction(String email) {
this.email = email;
}
...
// add accessors
}
To complete module settings we need a validator factory for the module like it is shown into the Gwt Devguide:
public final class ClientValidatorFactory extends AbstractGwtValidatorFactory {
// Syntax for multiple class: @GwtValidation({action1.class, action2.class})
@GwtValidation(SendMailAction.class)
public interface GwtValidator extends Validator {
}
@Override
public AbstractGwtValidator createValidator() {
return GWT.create(GwtValidator.class);
}
}
Now we are going to write a generic constraint validation manager which will be provided using Gin Injector. Here it is :
public class ClientValidation extends Validation {
private Validator validator;
private Set<ConstraintViolation> constraintViolations;
public ClientValidation() {
this.validator = buildDefaultValidatorFactory().getValidator();
}
public Set<ConstraintViolation> getConstraintViolations(Object object) {
this.constraintViolations = validator.validate(object);
return constraintViolations;
}
public String getPrimaryMessage() {
return constraintViolations.iterator().next().getMessage();
}
}
Finally we can configure one single instance into our module:
... bind(ClientValidation.class).in(Singleton.class);
and use it everywhere on client side with @Inject:
if (!clientValidation.getConstraintViolations(new sendMailAction(email)).isEmpty()) {
alert(clientValidation.getPrimaryMessage());
} else {
// do something
}
Thanks to the GWT team for those enhancements for client side validation.