#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);


326

被折叠的 条评论
为什么被折叠?



