一、背景
1.1 为啥自定义邮箱校验
validation 原生的 @Email 注解适合快速校验邮箱格式,但由于其局限性比如”123@123可以通过校验“,不适用于所有场景,如果项目需要高可靠性的邮箱验证,建议自定义邮箱格式校验
1.2 如何自定义邮箱校验
- 首先自定义校验注解
- 然后自定义校验逻辑
- 最后测试正反例状态
二、Action
2.1 自定义校验注解
可以通过实现 javax.validation.Constraint 自定义一个校验注解。
package com.pilot.meterage.web.utils.validation.annotation;
import com.pilot.meterage.web.utils.validation.constraint.EmailValidator;
import javax.validation.Constraint;
import javax.validation.Payload;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 自定义邮箱校验注解
*
* @author yangp
* @version 1.0
* @date 2024/11/16 10:00
*/
@Constraint(validatedBy = EmailValidator.class) // 指定校验器
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER}) // 适用范围
@Retention(RetentionPolicy.RUNTIME) // 注解保留时间
public @interface ValidEmail {
String message() default "邮箱格式不正确";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
2.2 自定义邮箱校验器
实现 jakarta.validation.ConstraintValidator 接口,自定义校验逻辑:
package com.pilot.meterage.web.utils.validation.constraint;
import com.pilot.meterage.web.utils.validation.annotation.ValidEmail;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintValidatorContext;
import java.util.regex.Pattern;
/**
* 自定义邮箱校验器
*
* @author yangp
* @version 1.0
* @date 2024/11/16 10:00
*/
public class EmailValidator implements ConstraintValidator<ValidEmail, String> {
/**
* 定义邮箱格式的正则表达式
*/
private static final String EMAIL_REGEX = "^[a-zA-Z0-9_.-]+@[a-zA-Z0-9-]+(\.[a-zA-Z]{2,6})+$";
private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REGEX);
@Override
public boolean isValid(String email, ConstraintValidatorContext context) {
// 空值时的校验逻辑(可按需求调整) 空值视为无效
if (email == null || email.trim().isEmpty()) {
return false;
}
// 匹配正则表达式
return EMAIL_PATTERN.matcher(email).matches();
}
}
2.3 在实体类中使用注解
使用自定义注解 @ValidEmail 校验邮箱字段:
public class Tenant {
@ValidEmail(message = "请输入有效的邮箱地址")
private String email;
// Getter 和 Setter
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
2.4 测试验证
通过 Validator 工具执行验证,返回校验结果:
import jakarta.validation.ConstraintViolation;
import jakarta.validation.Validation;
import jakarta.validation.Validator;
import jakarta.validation.ValidatorFactory;
import java.util.Set;
public class Main {
public static void main(String[] args) {
// 创建 Validator 工厂
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
Validator validator = factory.getValidator();
// 创建待校验对象
Tenant tenant = new Tenant();
tenant.setEmail("invalid_email.com"); // 测试用的无效邮箱
// 执行校验
Set<ConstraintViolation<Tenant>> violations = validator.validate(tenant);
// 输出校验结果
if (!violations.isEmpty()) {
for (ConstraintViolation<Tenant> violation : violations) {
System.out.println(violation.getMessage());
}
} else {
System.out.println("邮箱验证通过!");
}
}
}
2.5 运行结果
测试用例1
- 输入:
tenant.setEmail("example@test.com"); - 结果:
邮箱验证通过!
测试用例2
- 输入:
tenant.setEmail("invalid_email.com"); - 结果:
请输入有效的邮箱地址
测试用例3
- 输入:
tenant.setEmail("123@123"); - 结果:
请输入有效的邮箱地址