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

使用Java通过Gmail发邮件报错,求2022年适配方案及异常原因

Java通过Gmail发送邮件问题解答

该代码在2022年能否正常使用?

不能直接使用。Google在2022年彻底关闭了「不太安全的应用程序访问」权限,原代码中直接用Gmail账户密码登录SMTP的方式已经失效。必须改用应用专用密码(需开启两步验证)或OAuth 2.0认证才能正常连接Gmail的SMTP服务器。

抛出SSLHandshakeException异常的原因

1. TLS协议版本不兼容

Gmail的SMTP服务器仅支持TLS 1.2及以上版本的加密协议,但你的Java环境可能默认禁用了这些高版本协议(比如JDK 8早期版本、JDK 7及以下,默认未启用TLS 1.2),导致SSL握手时无法找到合适的协议,触发该异常。

2. 认证方式失效(叠加问题)

即使解决了协议问题,原代码用普通账户密码登录的方式也会失败——因为Google已经取消了普通密码用于SMTP登录的权限,必须使用应用专用密码或OAuth 2.0。

修复方案

方案一:启用两步验证并生成应用专用密码

  1. 登录你的Gmail账户,开启两步验证(2FA)
  2. 在Google账户设置中生成一个应用专用密码(这个密码仅用于你的Java程序,不会泄露主账户密码)
  3. 将代码中的PASSWORD替换为生成的应用专用密码

方案二:强制Java使用TLS 1.2协议

在代码的Properties配置中添加以下参数,指定SMTP使用TLS 1.2:

props.put("mail.smtp.ssl.protocols", "TLSv1.2");
props.put("mail.smtp.starttls.required", "true");

如果是旧版JDK,也可以修改JDK安装目录下的conf/security/java.security文件,找到jdk.tls.disabledAlgorithms项,移除其中的TLSv1.2(不推荐,会影响全局Java程序)。

方案三:升级JavaMail/Jakarta Mail版本

确保使用最新版本的邮件API(现在推荐使用Jakarta Mail,原JavaMail已迁移到Jakarta EE),旧版本可能对新TLS协议的支持不完善。

调整后的可运行代码示例

public class GmailTest {
   
    private static String USER_NAME = "your-username";  // 仅填@gmail.com前的部分
    private static String APP_PASSWORD = "your-generated-app-password"; // 替换为应用专用密码
    private static String RECIPIENT = "random.address@gmail.com";

    public static void main(String[] args) {
        String from = USER_NAME + "@gmail.com"; // 补全完整邮箱地址
        String pass = APP_PASSWORD;
        String[] to = { RECIPIENT };
        String subject = "Java send mail example";
        String body = "Welcome to JavaMail!";

        sendFromGMail(from, pass, to, subject, body);
    }

    private static void sendFromGMail(String from, String pass, String[] to, String subject, String body) {
        Properties props = System.getProperties();
        String host = "smtp.gmail.com";
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.smtp.starttls.required", "true");
        props.put("mail.smtp.ssl.protocols", "TLSv1.2"); // 指定TLS版本
        props.put("mail.smtp.host", host);
        props.put("mail.smtp.user", from);
        props.put("mail.smtp.password", pass);
        props.put("mail.smtp.port", "587");
        props.put("mail.smtp.auth", "true");

        // 使用Session.getInstance替代getDefaultInstance,避免复用旧配置
        Session session = Session.getInstance(props, new Authenticator() {
            @Override
            protected PasswordAuthentication getPasswordAuthentication() {
                return new PasswordAuthentication(from, pass);
            }
        });

        MimeMessage message = new MimeMessage(session);

        try {
            message.setFrom(new InternetAddress(from));
            InternetAddress[] toAddress = new InternetAddress[to.length];

            for( int i = 0; i < to.length; i++ ) {
                toAddress[i] = new InternetAddress(to[i]);
            }

            for( int i = 0; i < toAddress.length; i++) {
                message.addRecipient(Message.RecipientType.TO, toAddress[i]);
            }

            message.setSubject(subject);
            message.setText(body);
            Transport transport = session.getTransport("smtp");
            transport.connect(host, from, pass);
            transport.sendMessage(message, message.getAllRecipients());
            transport.close();
        
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 15:55:20