You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring中@Qualifier字段注入问题:邮箱校验始终返回false

问题

定义了两个实现CheckStringInterface的Bean:CheckPassword(标记@Primary)和CheckEmail,使用@Qualifier字段注入后,密码校验方法isStringValid能正常返回true,但邮箱校验无论输入格式正确与否始终返回false。相关代码及测试数据如下:

CheckPassword 实现类

@Service("CheckPassword")
@Primary
public class CheckPassword implements CheckStringInterface {

    private static final String regex_password = "^(?=.*[A-Z])(?=.*[a-z])(?=.*\\d)(?=.*[@#$%^&+=!])(?=\\S+$).{8,20}$";

    @Override
    public boolean isStringValid(String rawPassword) {
        Pattern pattern = Pattern.compile(regex_password);
        Matcher matcher = pattern.matcher(rawPassword);
        return matcher.matches();
    }
}

CheckEmail 实现类

@Service("CheckEmail")
public class CheckEmail implements CheckStringInterface {

    private static final String regex_password = "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\\\.[A-Z]{2,6}$";

    @Override
    public boolean isStringValid(String rawPassword) {
        Pattern pattern = Pattern.compile(regex_password);
        Matcher matcher = pattern.matcher(rawPassword);
        return matcher.matches();
    }
}

注入及使用代码

@Qualifier("CheckPassword")
private final CheckStringInterface checkPasswordFormat;

@Qualifier("CheckEmail")
private final CheckStringInterface checkEmailFormat;

// 其他注入字段省略

@Transactional 
public Integer register(RegisterDTO registerDTO, HttpServletRequest request){
    if (userService.findByEmail(registerDTO.email()) == null) {
        if (checkPasswordFormat.isStringValid(registerDTO.password()) == false
        || checkEmailFormat.isStringValid(registerDTO.email()) == false) {
            log.info("Wrong Format {}", checkPasswordFormat.isStringValid(registerDTO.password()));
            log.info("Wrong Format {}", checkEmailFormat.isStringValid(registerDTO.email()));
           return 0; // Wrong format email or password
        }
        // 后续注册逻辑省略
    } else {
        return 2; // Email already exists
    }
}

Swagger测试数据

{
  "email": "bonbon147852369@gmail.com",
  "fullName": "abcdABCD",
  "password": "Password@1234"
}

日志显示密码校验始终返回true,邮箱校验始终返回false,尝试更换正则表达式无效。


问题原因及解决方法

核心问题1:正则表达式转义错误

CheckEmail类中的邮箱正则里,匹配域名后缀点的部分写成了\\\\.。在Java字符串中,要将正则的元字符.转义为普通点,只需要两个反斜杠\\.;四个反斜杠会被编译成正则里的\\.,即要求匹配一个反斜杠加一个点,完全不符合实际邮箱格式,导致所有邮箱都匹配失败。

核心问题2:正则大小写不匹配

当前邮箱正则只允许大写字母([A-Z]),但测试用的邮箱是小写的gmail.com,即使转义正确,也会因大小写不匹配返回false。

额外问题:变量名混淆

CheckEmail类里的正则变量名写成了regex_password,虽不影响功能,但属于代码规范问题,建议改为regex_email提升可读性。


修正后的CheckEmail代码

@Service("CheckEmail")
public class CheckEmail implements CheckStringInterface {

    // 修正变量名、转义逻辑,同时支持大小写字母
    private static final String regex_email = "^[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,6}$";

    @Override
    public boolean isStringValid(String email) {
        // 也可以通过Pattern.CASE_INSENSITIVE标志实现大小写不敏感,无需修改正则里的[A-Z]
        // Pattern pattern = Pattern.compile(regex_email, Pattern.CASE_INSENSITIVE);
        Pattern pattern = Pattern.compile(regex_email);
        Matcher matcher = pattern.matcher(email);
        return matcher.matches();
    }
}

内容的提问来源于stack exchange,提问作者Hiếu Đỗ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 07:22:45