Java(JSP)项目使用Java Mail API发送邮件失败求解决方案
解决Java Mail API发送Gmail邮件时的530 STARTTLS错误
我之前踩过Gmail SMTP的这个坑,看你的错误日志和代码,问题主要出在SSL配置冲突和一些小的代码细节上,咱们一步步来修复:
错误原因分析
你的报错530 5.7.0 Must issue a STARTTLS command first,本质是因为你同时启用了mail.smtp.ssl.enable=true和mail.smtp.starttls.enable=true,但你用的是587端口——这个端口的工作机制是先建立明文连接,再通过STARTTLS命令升级为SSL加密;而mail.smtp.ssl.enable=true是强制一开始就用SSL连接(对应465端口),两者冲突导致SMTP服务器拒绝你的请求。
具体解决方案
1. 修正SMTP配置参数
把你的Properties配置改成下面这样,去掉冲突项,适配587端口的要求:
Properties props = new Properties(); props.put("mail.smtp.starttls.enable", "true"); // 必须开启,587端口依赖这个 props.put("mail.smtp.host", "smtp.gmail.com"); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.port", "587"); props.put("mail.debug", "false"); // 移除这两个配置:587端口不需要SSL Socket Factory和强制SSL // props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory"); // props.put("mail.smtp.ssl.enable", "true");
2. 检查Gmail账号的安全设置
这是很多人容易忽略的点:
- 如果你的Gmail账号开启了两步验证(2FA):不能直接用原密码登录SMTP,必须去Google账号设置里生成一个应用专用密码(App Password),用这个密码替换代码里的
password字段。 - 如果没开启2FA:需要在Google账号的“安全”选项里,开启“允许不太安全的应用访问”(注意:这个选项现在默认隐藏,你可能需要先搜索开启这个开关)。
- 同时确保你的Gmail账号已经启用了IMAP/SMTP服务(在Gmail设置的“转发和POP/IMAP”里开启)。
3. 修复代码里的变量错误
看你的代码里有一行:
InternetAddress from = new InternetAddress(from, name);
这里的from和name都是未定义的变量(你定义的是from1和FROM_NAME),会导致编译错误,应该改成:
InternetAddress from = new InternetAddress(from1, FROM_NAME);
修正后的完整MailUtil代码
import java.io.UnsupportedEncodingException; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import javax.mail.Authenticator; import javax.mail.Message; import javax.mail.MessagingException; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeMessage; public class MailUtil { private String from1 = "fromemail@gmail.com"; private String password = "你的应用专用密码或原密码"; private String FROM_NAME = "abc"; public boolean sendMail(String[] recipients, String[] bccRecipients, String subject, String message) { try { Properties props = new Properties(); props.put("mail.smtp.starttls.enable", "true"); props.put("mail.smtp.host", "smtp.gmail.com"); props.put("mail.smtp.auth", "true"); props.put("mail.smtp.port", "587"); props.put("mail.debug", "false"); Session session = Session.getDefaultInstance(props, new javax.mail.Authenticator() { protected PasswordAuthentication getPasswordAuthentication() { return new PasswordAuthentication(from1, password); } }); Message msg = new MimeMessage(session); InternetAddress from = new InternetAddress(from1, FROM_NAME); msg.setFrom(from); InternetAddress[] toAddresses = new InternetAddress[recipients.length]; for (int i = 0; i < recipients.length; i++) { toAddresses[i] = new InternetAddress(recipients[i]); } msg.setRecipients(Message.RecipientType.TO, toAddresses); if (bccRecipients != null && bccRecipients.length > 0) { InternetAddress[] bccAddresses = new InternetAddress[bccRecipients.length]; for (int j = 0; j < bccRecipients.length; j++) { bccAddresses[j] = new InternetAddress(bccRecipients[j]); } msg.setRecipients(Message.RecipientType.BCC, bccAddresses); } msg.setSubject(subject); msg.setContent(message, "text/plain"); Transport.send(msg); return true; } catch (UnsupportedEncodingException ex) { Logger.getLogger(MailUtil.class.getName()).log(Level.SEVERE, null, ex); return false; } catch (MessagingException ex) { Logger.getLogger(MailUtil.class.getName()).log(Level.SEVERE, null, ex); return false; } } }
额外注意事项
- 如果你想改用465端口,那配置要改成:开启
mail.smtp.ssl.enable=true,端口设为465,同时可以加上mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory,但要关闭mail.smtp.starttls.enable。 - 测试时可以把
mail.debug改成true,这样能看到更详细的SMTP交互日志,方便排查问题。
内容的提问来源于stack exchange,提问作者sanjay goswami
相关产品推荐
相关产品推荐

