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

Spring Boot集成Gmail SMTP发送邮件遇SSL握手协议错误求助

问题描述

本地Spring Boot应用基于smtp.gmail.com实现邮件发送时,出现SSL握手错误,日志如下:

2022-09-11 12:17:31,499 [DEBUG] from org.springframework.web.servlet.DispatcherServlet in http-nio-1995-exec-1 - Failed to complete request: org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Can't send command to SMTP host;
  nested exception is:
        javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate). Failed messages: javax.mail.MessagingException: Can't send command to SMTP host;
  nested exception is:
        javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate); message exceptions (1) are:
Failed message 1: javax.mail.MessagingException: Can't send command to SMTP host;
  nested exception is:
        javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
2022-09-11 12:17:31,500 [DEBUG] from org.springframework.security.web.context.SecurityContextPersistenceFilter in http-nio-1995-exec-1 - Cleared SecurityContextHolder to complete request
2022-09-11 12:17:31,501 [ERROR] from org.apache.catalina.core.ContainerBase.[Tomcat-1].[localhost].[/].[dispatcherServlet] in http-nio-1995-exec-1 - Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.mail.MailSendException: Mail server connection failed; nested exception is javax.mail.MessagingException: Can't send command to SMTP host;
  nested exception is:
        javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate). Failed messages: javax.mail.MessagingException: Can't send command to SMTP host;
  nested exception is:
        javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate); message exceptions (1) are:
Failed message 1: javax.mail.MessagingException: Can't send command to SMTP host;
  nested exception is:
        javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)] with root cause
javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)
        at java.base/sun.security.ssl.HandshakeContext.<init>(HandshakeContext.java:172)

当前邮件配置类:

@Configuration
public class MailConfig {

    @Bean
    public JavaMailSender getJavaMailSender() {
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        mailSender.setHost("smtp.gmail.com");
        mailSender.setPort(587);

        mailSender.setUsername(MyConstants.MY_EMAIL);
        mailSender.setPassword(MyConstants.MY_PASSWORD);

        Properties props = mailSender.getJavaMailProperties();
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.debug", "true");

        return mailSender;
    }

}

常量类:

public class MyConstants {

    public static final String MY_EMAIL = "myMail@gmail.com";
    public static final String MY_PASSWORD = "passwordGeneretedFromGmail";
    public static final String FRIEND_EMAIL = "senderToMail@gmail.com";

}

控制器类:

@Controller
@RequestMapping("/api")
public class SimpleEmailExampleController {

    @Autowired
    public JavaMailSender emailSender;

    @ResponseBody
    @RequestMapping("/sendSimpleEmail")
    public String sendSimpleEmail() {

        // Create a Simple MailMessage.
        SimpleMailMessage message = new SimpleMailMessage();

        message.setTo(MyConstants.FRIEND_EMAIL);
        message.setSubject("Test Simple Email");
        message.setText("Hello, Im testing Simple Email");

        // Send Message!
        this.emailSender.send(message);

        return "Email Sent!";
    }

}

配置逻辑无明显问题,寻求解决该错误的配置调整方案。

解决方案

该错误源于JDK默认禁用了部分旧版TLS协议,而Gmail SMTP在STARTTLS模式下需要兼容的协议支持。可通过以下方式解决:

方法1:在邮件配置中指定SSL协议

修改MailConfig,添加指定TLSv1.2协议的配置项,确保握手时使用兼容协议:

@Configuration
public class MailConfig {

    @Bean
    public JavaMailSender getJavaMailSender() {
        JavaMailSenderImpl mailSender = new JavaMailSenderImpl();
        mailSender.setHost("smtp.gmail.com");
        mailSender.setPort(587);

        mailSender.setUsername(MyConstants.MY_EMAIL);
        mailSender.setPassword(MyConstants.MY_PASSWORD);

        Properties props = mailSender.getJavaMailProperties();
        props.put("mail.transport.protocol", "smtp");
        props.put("mail.smtp.auth", "true");
        props.put("mail.smtp.starttls.enable", "true");
        props.put("mail.debug", "true");
        // 添加以下两行配置,强制指定使用TLSv1.2协议
        props.put("mail.smtp.ssl.protocols", "TLSv1.2");
        props.put("mail.smtp.starttls.required", "true");

        return mailSender;
    }

}

方法2:修改JDK全局安全配置

找到JDK安装目录下的jre/lib/security/java.security文件,调整禁用协议列表:

  • 定位jdk.tls.disabledAlgorithms配置行,移除TLSv1.2(若存在),确保仅禁用不兼容的旧协议,示例:
    jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA
    

注意:此修改会影响所有使用该JDK的应用,适合全局需要调整协议的场景。

方法3:通过JVM启动参数指定协议

在应用启动时添加JVM参数,强制客户端使用TLSv1.2:

-Djdk.tls.client.protocols=TLSv1.2

或同时指定HTTPS协议:

-Dhttps.protocols=TLSv1.2 -Djdk.tls.client.protocols=TLSv1.2

额外检查项

  • 确认Gmail账号已开启两步验证,且使用的是正确生成的应用专用密码,而非账号原密码。
  • 检查本地网络是否能正常访问smtp.gmail.com的587端口,避免防火墙、代理拦截连接。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 16:10:32