收件邮箱无效时Transport.send()的异常表现问题
解决JavaMail发送邮件时无效收件箱导致程序挂起的问题
一、添加SMTP超时配置
默认情况下JavaMail未设置SMTP连接和发送超时,遇到无效收件人时会无限等待。在Properties中添加以下超时属性,让程序在指定时间内无响应就抛出异常:
prop.put("mail.smtp.connectiontimeout", "5000"); // 连接超时,单位毫秒 prop.put("mail.smtp.timeout", "5000"); // 发送超时,单位毫秒 prop.put("mail.smtp.writetimeout", "5000"); // 写入超时,单位毫秒
二、提前验证收件人邮箱格式
在发送前先过滤格式明显错误的邮箱,避免向无效地址发起SMTP请求:
// 单个收件人验证 try { InternetAddress address = new InternetAddress(recipient); address.validate(); } catch (AddressException e) { System.err.println("收件人邮箱格式无效: " + recipient); return; } // 多个收件人(用逗号分隔)的验证 for (String addrStr : recipient.split(",")) { InternetAddress address = new InternetAddress(addrStr.trim()); address.validate(); }
三、开启调试日志定位问题
开启JavaMail调试模式,查看SMTP通信的详细过程,明确程序卡壳的环节:
// 在Properties中添加 prop.put("mail.debug", "true"); // 或者直接给Session设置 session.setDebug(true);
调试日志会输出SMTP命令与服务器响应,帮助排查具体问题。
四、适配Gmail SMTP的特殊限制
如果使用Gmail的SMTP服务,需注意:
- 开启两步验证的账号,必须使用应用专用密码替代原密码
- 未开启两步验证的账号,需在Google账号设置中启用"不太安全的应用访问"(推荐优先使用应用密码)
- 需在Gmail设置的「转发和POP/IMAP」中启用IMAP服务
修改后的完整代码示例
public class SendEmailTLS { public static void email_sender(String recipient, String subject, String content) { System.out.println("Sending email(s)..."); final String username = "sender's email"; final String password = "sender's password"; Properties prop = new Properties(); prop.put("mail.smtp.host", "smtp.gmail.com"); prop.put("mail.smtp.port", "587"); prop.put("mail.smtp.auth", "true"); prop.put("mail.smtp.starttls.enable", "true"); // TLS // 添加超时配置 prop.put("mail.smtp.connectiontimeout", "5000"); prop.put("mail.smtp.timeout", "5000"); prop.put("mail.smtp.writetimeout", "5000"); // 开启调试(排查问题时启用) prop.put("mail.debug", "true"); Session session = Session.getInstance(prop, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(username, password); } }); try { // 提前验证收件人格式 for (String addrStr : recipient.split(",")) { InternetAddress address = new InternetAddress(addrStr.trim()); address.validate(); } Message message = new MimeMessage(session); message.setFrom(new InternetAddress(username)); message.setRecipients( Message.RecipientType.TO, InternetAddress.parse(recipient) ); message.setSubject(subject); message.setText(content); Transport.send(message); System.out.println("Email Sent"); } catch (AddressException e) { System.err.println("收件人邮箱格式错误: " + e.getMessage()); } catch (MessagingException e) { System.err.println("发送邮件失败: " + e.getMessage()); e.printStackTrace(); } } }
内容的提问来源于stack exchange,提问作者scout
相关产品推荐
相关产品推荐

