Email注解默认校验规则

#Email注解的校验规则与自己前端的不一致#

结论,Jakarta的Email注解的默认实现是依赖于hibernate-validator的。(可以指定正则属性来使用自己的校验规则)

实测下来是存在问题的xxx@x可以校验通过,与主流定义不太一致,请谨慎使用。

生成前端代码:

// 修正后的本地部分正则
const LOCALPART_REGEX =
  /(?:[a-z0-9!#$%&'*+/=?^_`{|}~\u0080-\uffff-]+|"(?:[a-z0-9!#$%&'*.(),<>\[\]:;  @+/=?^_`{|}~\u0080-\uffff-]|\\\\\\\\|\\\\")+")(?:\.(?:[a-z0-9!#$%&'*+/=?^_`{|}~\u0080-\uffff-]+|"(?:[a-z0-9!#$%&'*.(),<>\[\]:;  @+/=?^_`{|}~\u0080-\uffff-]|\\\\\\\\|\\\\")+"))*/i;

// 修正后的域名部分正则(主要修正了 \uffff 和 IPv6 部分)
const DOMAIN_REGEX =
  /(?:(?:[a-z\u0080-\uffff0-9!#$%&'*+/=?^_`{|}~]-*)*[a-z\u0080-\uffff0-9!#$%&'*+/=?^_`{|}~]+(?:\.(?:[a-z\u0080-\uffff0-9!#$%&'*+/=?^_`{|}~]-*)*[a-z\u0080-\uffff0-9!#$%&'*+/=?^_`{|}~]+)*|\[(?:[0-9]{1,3}\.){3}[0-9]{1,3}\]|\[IPv6:(?:(?:[0-9a-fA-F]{1,4}:){7}(?:[0-9a-fA-F]{1,4}|:)|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?::[0-9a-fA-F]{1,4}){1,6}|:(?::[0-9a-fA-F]{1,4}){1,7}|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-z]+|::(?:ffff(:0{1,4})?:)?(?:(?:25[0-5]|2[0-4][0-9]|1?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|1?[0-9][0-9]?)|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|2[0-4][0-9]|1?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|1?[0-9][0-9]?))\])/i;
const checkEmail = function (rule, value, callback) {
  // 转换为字符串并去除首尾空格
  const emailString = String(value).trim();

  // 快速失败:检查整体长度(RFC 标准最大254字符)
  if (emailString.length > 254) {
    callback(new Error("请输入正确的电子邮箱"));
    return;
  }

  // 查找最后一个@符号的位置(兼容本地部分包含@的情况)
  const atIndex = emailString.lastIndexOf("@");
  // 检查@符号是否存在且位置合法(不能在开头或末尾)
  if (atIndex <= 0 || atIndex === emailString.length - 1) {
    callback(new Error("请输入正确的电子邮箱"));
    return;
  }

  // 分割本地部分和域名部分
  const localPart = emailString.substring(0, atIndex);
  const domainPart = emailString.substring(atIndex + 1);

  // 检查本地部分长度(RFC 标准最大64字符)
  if (localPart.length > 64) {
    callback(new Error("请输入正确的电子邮箱"));
    return;
  }

  // 检查域名部分长度(建议不超过253字符)
  if (domainPart.length > 253) {
    callback(new Error("请输入正确的电子邮箱"));
    return;
  }

  // 使用严谨的正则表达式验证本地部分格式
  if (!LOCALPART_REGEX.test(localPart)) {
    callback(new Error("请输入正确的电子邮箱"));
    return;
  }

  // 使用严谨的正则表达式验证域名部分格式
  if (!DOMAIN_REGEX.test(domainPart)) {
    callback(new Error("请输入正确的电子邮箱"));
    return;
  }

  // 所有验证均通过
  callback();
};

在8.8.1版本中。默认实现为如下图位置

用户名部分:

private static final Pattern LOCAL_PART_PATTERN = Pattern.compile("(?:[a-z0-9!#$%&'*+/=?^_`{|}~\u0080-\uffff-]+|\"(?:[a-z0-9!#$%&'*.(),<>\\[\\]:;  @+/=?^_`{|}~\u0080-\uffff-]|\\\\\\\\|\\\\\\\")+\")(?:\\.(?:[a-z0-9!#$%&'*+/=?^_`{|}~\u0080-\uffff-]+|\"(?:[a-z0-9!#$%&'*.(),<>\\[\\]:;  @+/=?^_`{|}~\u0080-\uffff-]|\\\\\\\\|\\\\\\\")+\"))*", 2);

域名部分:

private static final Pattern EMAIL_DOMAIN_PATTERN = Pattern.compile("(?:[a-z\u0080-\uffff0-9!#$%&'*+/=?^_`{|}~]-*)*[a-z\u0080-\uffff0-9!#$%&'*+/=?^_`{|}~]++(?:\\.(?:[a-z\u0080-\uffff0-9!#$%&'*+/=?^_`{|}~]-*)*[a-z\u0080-\uffff0-9!#$%&'*+/=?^_`{|}~]++)*|\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\]|\\[IPv6:(?:(?:[0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,7}:|(?:[0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|(?:[0-9a-fA-F]{1,4}:){1,5}(?::[0-9a-fA-F]{1,4}){1,2}|(?:[0-9a-fA-F]{1,4}:){1,4}(?::[0-9a-fA-F]{1,4}){1,3}|(?:[0-9a-fA-F]{1,4}:){1,3}(?::[0-9a-fA-F]{1,4}){1,4}|(?:[0-9a-fA-F]{1,4}:){1,2}(?::[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:(?:(?::[0-9a-fA-F]{1,4}){1,6})|:(?:(?::[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(?::[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(?:ffff(:0{1,4}){0,1}:){0,1}(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])|(?:[0-9a-fA-F]{1,4}:){1,4}:(?:(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9])\\.){3,3}(?:25[0-5]|(?:2[0-4]|1{0,1}[0-9]){0,1}[0-9]))\\]", 2);

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值