2

I have created a bean validator that I apply to my bean setter method. Instead of getting a JSF validation error, I get an exception raised. Is there a way to make this work, or I should go with a traditional JSF validator?

//Bean Method
public void setGuestPrimaryEmail(@ValidEmail String email){
   guest.getEmails().get(0).setValue(email);
}

//Validator interface
@Target({ElementType.FIELD,ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = EmailValidator.class)
public @interface ValidEmail {

    String message() default "{invalid}";

    Class<? extends Payload>[] payload() default {};

    Class<?>[] groups() default {};

}

//Validator impl
public class EmailValidator implements ConstraintValidator<ValidEmail, String> {

    private Pattern p;

    @Override
    public void initialize(ValidEmail constraintAnnotation) {
        p = java.util.regex.Pattern
                .compile("[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?");
    }

    @Override
    public boolean isValid(String value, ConstraintValidatorContext context) {
        if (DothatUtils.isEmpty(value)) {
            return true;
        }

        boolean invalid = !p.matcher(value).matches();
        if (invalid)
            return false;

        return true;
    }

}

Exception:

2013-11-30T20:58:41.747+0000|SEVERE: javax.faces.component.UpdateModelException: 
javax.el.ELException: /index.xhtml @144,86 value="....": 
javax.validation.ConstraintViolationException: 1 constraint violation(s) occurred during method validation.

Note: I am using GF4 with JSF 2.2.4. If I place my custom annotation on the field, it works as expected.

Ioannis Deligiannis
  • 2,679
  • 5
  • 25
  • 48
  • Can [this](http://stackoverflow.com/a/7548821/1391249) help you? – Tiny Nov 30 '13 at 21:25
  • Thanks for your answer, but Validation is working properly if I annotate my entities. Will update my question. – Ioannis Deligiannis Nov 30 '13 at 21:52
  • How does your constraint validator (`EmailValidator`) look like? – Tiny Nov 30 '13 at 22:16
  • I will update the question with the code, but it works perfectly if applied on a field rather than a method param. – Ioannis Deligiannis Nov 30 '13 at 22:27
  • Could you please try to add `ElementType.METHOD` to the `@Target` annotation on your constraint descriptor? – Tiny Nov 30 '13 at 22:32
  • Your suggestion didn't work by itself. I was wrongly putting the validator on the `setter` rather than the `getter`. When I moved the annotation to the getter, it worked fine. Would you like to post this as the answer? – Ioannis Deligiannis Nov 30 '13 at 22:42
  • Questions can be answered by experienced people that I'm not :) (I have first time responded to a question). You may post your own solution as an answer, instead. Thanks. – Tiny Nov 30 '13 at 22:48

1 Answers1

2

ElementType.PARAMETER is not recognized by the default JSR303 bean validation provider.

From JSR303 1.0 specification:

2.1 Constraint annotation

...

Constraint annotations can target any of the following ElementTypes:

  • FIELD for constrained attributes
  • METHOD for constrained getters
  • TYPE for constrained beans
  • ANNOTATION_TYPE for constraints composing other constraints

While other ElementTypes are not forbidden, the provider does not have to recognize and process constraints placed on such types. Built-in types do support PARAMETER and CONSTRUCTOR to allow Bean Validation provider specific extensions. It is considered good practice to follow the same approach for custom annotations.

You really have to put the constraint annotation on the property (identified by ElementType.FIELD) or on the getter (identified by ElementType.METHOD). Note that a constrained setter is not supported!

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Hi BalusC, can we use parameterized validation? could you provide an example? That will help alot. Thanks in advance. – Mukundhan May 05 '20 at 13:29