JSR303: attempt to configure constraint violation for subpath binding in class level relationship constraint validator

I use JSR303 and create a class-level constraint that compares the password and its confirmation in a form that I will name here as the @SameAs constraint. Ideally, I would like to associate the restriction with the intended purpose (confirmPassword), but obviously the closing bean is not available for password retrieval. - therefore, class level restriction.

I read with interest other posts demonstrating how to use class-level constraints to check relationships, but cannot find anything explaining how the constraint constraint can be configured to bind to a subpath, in which case one of two fields in this regard.

My question is this: how to associate a restriction violation message with the confirmPassword field instead of a top-level object? I tried using the javax.Validator.validate (target, context) context parameter, but adding Node to the validator for @SameAs throws an exception for the next cascade constraint (trying to extract confirmation Password → orderNumber, not order → orderNumber).

At the moment, I resorted to an ugly blog, creating an additional property that stores a restriction message that breaks out for use next to the confirmPassword input field on the web layer.

Of course, I missed something here ... see example below

Thanks for any comments.

Example

@Constraint( validatedBy = { SamePwdAsValidator.class}) public interface SamePwdAs {//... } //Using passwords in an order doesn't make sense - only for demo purpose @SamePwdAs( message = "Password and confirmation must match" ...) public class Order { @NotNull @Size(....) String pwd; //where I would really like to use @SameAs, and associate a violation String pwdConfirm; @NotNull (...) @Pattern (....) String orderNumber; //...getters/setters } public class SamePwdAsValidator implements javax.validation.Validator { //... public boolean isValid( Object target, ValidationContext ctx) { String tgt = target.getPwd(), other = target.getPwdConfirm() boolean isValid = tgt.equals( other); if ( !isValid) { //try to configure the context subpath for pwdConfirm to associate this constraint violation with: I tried //ctx.addNode( 'pwdConfirm').addConstraintViolation() which doesn't work, as the next validator will //bump into trying to extract Order.pwdConfirm.orderNumber and throw a NoPropertyFoundException or the like } return isValid; } 
+6
java constraints bean-validation
source share
1 answer

I will give 2 answers.

Answer 1 , which is trying to answer your question:

I use a utility like:

 public static final void recreateConstraintViolation(ConstraintValidatorContext constraintValidatorContext, String errorCode, String fieldName) { constraintValidatorContext.disableDefaultConstraintViolation(); constraintValidatorContext.buildConstraintViolationWithTemplate(errorCode). addNode(fieldName).addConstraintViolation(); } 

And then, in your validator, where you compare two passwords:

 if ( !isValid) { for (String fieldName : fieldNames) { CustomConstraintUtils.recreateConstraintViolation(constraintValidatorContext, "password.password2.mismatch", fieldName); } return false; } 

Answer 2

I would suggest using a security infrastructure such as Spring Security to ensure password compliance, as I assume your use-case deals with user login.

+5
source share

All Articles