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

Spring Boot starter-mail发送邮件时接口无限挂起无响应问题

问题根因
  • 超时配置未生效:你在Controller中手动实例化JavaMailSenderImpl时,仅注入了host、port、账号、密码四个基础参数,application.properties中配置的三类超时参数、SMTP认证、加密传输等配置完全没有被加载到新建的邮件发送实例中。一旦SMTP握手、指令交互阶段出现网络异常,程序没有超时中断机制,就会无限阻塞。
  • 参数校验逻辑失效:BindingResult仅能捕获紧邻的、被@Valid注解标记的参数的校验错误,你的代码中既没有给ConfirmationEmail参数加@Valid注解触发校验,参数校验规则本身就不会运行。
  • 发件人地址不符合SMTP服务规则:你使用的Mailtrap是测试类邮件服务,要求发件人地址必须是当前账号下已完成验证的地址,你直接将请求传入的第三方gmail地址设为发件人,会被SMTP服务直接拒绝连接,部分场景下会导致请求挂起。
  • 重复造轮子导致配置遗漏:引入spring-boot-starter-mail后,Spring Boot会自动读取spring.mail.*前缀的所有配置,构建好可用的JavaMailSender Bean,你自定义EmailConfig类、手动new发送实例的写法,完全绕开了框架的自动配置逻辑,漏掉了大量必要的底层参数。
修复步骤
  1. 删除自定义的EmailConfig类,不需要自己读取邮件配置,直接注入Spring自动生成的JavaMailSender实例即可。
  2. 修正Controller层代码:给请求体参数加@Valid注解,保证BindingResult紧跟在被校验参数之后,不要手动创建JavaMailSenderImpl实例,修正发件人地址为Mailtrap账号下已验证的邮箱。
  3. 补全SMTP必要配置,开启认证和传输加密,保证超时规则正常加载。
  4. 本地验证SMTP端口连通性,排除网络层拦截问题。

修正后代码

EmailController.java

@RestController
@RequestMapping(path = "api/v1/email")
public class EmailController {

    private final JavaMailSender javaMailSender;

    // 直接注入Spring自动配置好的邮件发送实例
    public EmailController(JavaMailSender javaMailSender) {
        this.javaMailSender = javaMailSender;
    }

    @PostMapping
    public ResponseEntity<String> sendEmail(@Valid @RequestBody ConfirmationEmail confirmationEmail,
                                            BindingResult bindingResult) throws ValidationException {
        if (bindingResult.hasErrors()) {
            throw new ValidationException("请求参数不合法");
        }

        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        // 此处替换为你在Mailtrap后台验证过的发件人邮箱,不要使用请求传入的外部地址
        simpleMailMessage.setFrom("your-authorized-sender@example.com");
        simpleMailMessage.setTo("mail@gmail.com");
        simpleMailMessage.setSubject("Test Subject from " + confirmationEmail.getSenderName());
        simpleMailMessage.setText(confirmationEmail.getConfirmationBody());

        javaMailSender.send(simpleMailMessage);
        return ResponseEntity.ok("邮件发送成功");
    }
}

application.properties

spring.mail.host=smtp.mailtrap.io
spring.mail.port=2525
spring.mail.username=替换为你的Mailtrap账号SMTP用户名
spring.mail.password=替换为你的Mailtrap账号SMTP密码
# 开启SMTP认证
spring.mail.properties.mail.smtp.auth=true
# 开启TLS加密传输
spring.mail.properties.mail.smtp.starttls.enable=true
# 超时配置,Spring自动配置会自动加载以下参数
spring.mail.properties.mail.smtp.connectiontimeout=5000
spring.mail.properties.mail.smtp.timeout=3000
spring.mail.properties.mail.smtp.writetimeout=5000

ConfirmationEmail.java

原有代码逻辑不需要调整,保留现有getter、setter和校验注解即可。

额外排查项

如果完成以上修改后请求仍然阻塞,先在部署服务的机器上执行telnet smtp.mailtrap.io 2525测试端口连通性:

  • 如果连接失败,说明本地网络或防火墙拦截了对应SMTP端口,可以换成Mailtrap提供的587、465等其他SMTP端口重试。
  • 如果连接正常,检查填写的SMTP用户名、密码是否和Mailtrap后台提供的测试账号一致,账号信息错误也可能导致握手阶段挂起。

内容的提问来源于stack exchange,提问作者Radwan Afiouni

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.29 18:36:23