Hi,
I'm building a registration form with two password fields being validated on client side using GWT Validation framework.
Is there any constraint for doing so (validating a value against another field)? Or what's the best way to implement this (should work on server, too)?
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Constraint(validatedBy = PasswordsEqualValidator.class) @Documented public @interface PasswordsEqual { String DEFAULT_MESSAGE = "Passwords must be the same"; String message() default DEFAULT_MESSAGE; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }
Then you would need a custom validator. Mine looks like this:
public class PasswordsEqualValidator implements ConstraintValidator<PasswordsEqual, CreateAccountBean> {
@Override
public void initialize(PasswordsEqual constraintAnnotation) {}
@Override
public boolean isValid(CreateAccountBean value, ConstraintValidatorContext context) {
if( value == null )
return true;
String password = value.getPassword();
String confirmPassword = value.getConfirmPassword();
if( password == null && confirmPassword == null )
return true;
if( password != null && password.equals(confirmPassword) )
return true;
return false;
}
}
Then annotate the javabean class being validated with @PasswordsEqual
This works on the client and server.
I'm not really sure why people use it considering vanilla GWT supports JSR303 (the documentation is pretty bad admittedly).
Hi,I was looking at the link http://www.gwtproject.org/doc/latest/DevGuideRequestFactory.html#validation , and it's not clear when the validation is executed. it seams it is executed each time data is sent to the server!!???.
If it's the case, this could be a performance problem since we might have some complex validation processes that we want to execute only when we call some service methods (in a perfect world we would be able to decide on the client or server side if we want to execute a validation or skip it).
this is really an issue because RequestFactory is thought as a rigid architecture : the user entered data can be reused only if the validation failed (otherwise the EntityProxy becomes frozen, and there's no easy way to duplicate an EntityProxy). So the best way to check a precondition constraint is in the validation process. The issue is that you have the choice between two scenarios:
- You can do your checks in a specific service method, throw an exception and handle that in the onFailure() client side method. But!!! you cannot reuse the EntityProxy anymore since it's frozen
- You can do your checks in the validation phase, so you can keep your EntityProxy reuasable, But!!! the validation is made each time you send data to the server (which can be a hard resource consumption issue)
So the question is: is there a way to controle whether the server side validation process has to be made? (a per service method configuration or a runtime check switch)?
If it's the case, this could be a performance problem since we might have some complex validation processes that we want to execute only when we call some service methods (in a perfect world we would be able to decide on the client or server side if we want to execute a validation or skip it).The idea is that you only validate those things that MUST be validated (and for that, you just put them in the default group, and other constraints in other groups; or you put them in a specific group and you use a ServiceLayerDecorator with an overridden validate() method to validate only that specific group).
this is really an issue because RequestFactory is thought as a rigid architecture : the user entered data can be reused only if the validation failed (otherwise the EntityProxy becomes frozen, and there's no easy way to duplicate an EntityProxy). So the best way to check a precondition constraint is in the validation process. The issue is that you have the choice between two scenarios:
- You can do your checks in a specific service method, throw an exception and handle that in the onFailure() client side method. But!!! you cannot reuse the EntityProxy anymore since it's frozen
- You can do your checks in the validation phase, so you can keep your EntityProxy reuasable, But!!! the validation is made each time you send data to the server (which can be a hard resource consumption issue)
So the question is: is there a way to controle whether the server side validation process has to be made? (a per service method configuration or a runtime check switch)?I'm sure you can come up with clever tricks to pass some value down to a ServiceLayerDecorator's validate() method (e.g. through a request header, or appending data to the payload and stripping it in a servlet filter).
I'm rather supportive of RF but it doesn't fit everyone's use-case (well, using only ValueProxies makes it a good replacement for GWT-RPC with an added batching feature, at the expense of bigger payloads but without the hassle of serialization policies).Wrt validation, RF works best if you restrict validation to "per field" (value ranges, patterns, etc.) or otherwise fast checks, and allow invalid data (wrt. other (business) constraint violations) to be persisted, along with a valid/invalid flag of some sort. Then depending on the valid/invalid flag you can decide whether some actions on the persisted data are possible or not. Actually, that's the approach that best fits "the web", because you don't want to "get in the way" of the user and risk all his "work" to be lost (browser crash, broken connectivity, etc.): when I tell you to save, just save, when I tell you to "act", feel free to refuse if the saved data is wrong. It generally requires totally rethinking the way you work with data and the way you store it, so it might only be possible in greenfield projects with enough budget and sufficiently skilled architects/developers.The alternative is to "flush" data (and edit()) into your proxies only when needed; that way you can just "flush" again in newly-edit()ed proxies should an error happen (if you use the Editor framework, that means *not* using the RequestFactoryEditorDriver; you could use "edit on write" proxies that read from frozen RF proxies and only edit() and write into RF proxies on flush; or you could copy data from the RF proxies to "view model" objects, and then edit the RF proxies and copy back again just before fire()ing the request)
The idea is :
Do you think I should enter a feature request with this or is there already something happening in GWT internally?
The idea is :"Since GWT is rigid in "when things should happen" (phases), it should be more permissive in how you manage each step"Since it imposes that validation must happen only the validation phase, it should allow to better tune how you do your validation.