Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Hibernate validator: @Email accepts ask@stackoverflow as valid?

I'm using the @Email annotation to validate an e-mail address. The issue I'm having is that it's accepting things like ask@stackoverflow as a valid e-mail address. I guess this is because they want to support intranet addresses, but I can't seem to find a flag so it does check for an extension.

Do I really need to switch to @Pattern (and any recommendations for an e-mail pattern that's flexible) or am I missing something?

like image 671
jack Avatar asked Dec 16 '10 10:12

jack


3 Answers

Actually, @Email from Hibernate Validator uses regexp internally. You can easily define your own constraint based on that regexp, modified as you need (note the + at the end of DOMAIN):

@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = {})
@Pattern(regexp = Constants.PATTERN, flags = Pattern.Flag.CASE_INSENSITIVE)
public @interface EmailWithTld {
    String message() default "Wrong email";
    Class<?>[] groups() default { };
    Class<? extends Payload>[] payload() default { };
}

interface Constants {
    static final String ATOM = "[a-z0-9!#$%&'*+/=?^_`{|}~-]";
    static final String DOMAIN = "(" + ATOM + "+(\\." + ATOM + "+)+";
    static final String IP_DOMAIN = "\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\]";

    static final String PATTERN =
            "^" + ATOM + "+(\\." + ATOM + "+)*@"
                    + DOMAIN
                    + "|"
                    + IP_DOMAIN
                    + ")$";
}
like image 30
axtavt Avatar answered Nov 14 '22 22:11

axtavt


You can also use constraint composition as a work-around. In the example below, I rely on the @Email validator to do the main validation, and add a @Pattern validator to make sure the address is in the form of [email protected] (I don't recommend using just the @Pattern below for regular Email validation)

@Email(message="Please provide a valid email address")
@Pattern(regexp=".+@.+\\..+", message="Please provide a valid email address")
@Target( { METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = {})
@Documented
public @interface ExtendedEmailValidator {
    String message() default "Please provide a valid email address";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}
like image 154
Matt Avatar answered Nov 14 '22 23:11

Matt


While it still possible to implement your own validator or compose a custom one that will aggregate @Email and @Pattern, you don't have to do this anymore!

In one of the recent releases (it's definitely is present in hibernate-validator 6.0.x), @Email has got new regexp attribute that is "an additional regular expression the annotated element must match". In other words, here is a new approach:

@Email(regexp = ".+@.+\\..+")
private String email;
like image 21
Slava Semushin Avatar answered Nov 14 '22 22:11

Slava Semushin