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

Spring Boot 3.2.5 Gmail邮件发送[EOF]错误求助

Gmail邮件发送EOF异常排查方案

问题描述

在Windows 11 Pro系统上使用Spring Boot 3.2.5实现Gmail邮件发送功能,代码在其他设备可正常运行,但本地始终发送失败,报错org.springframework.mail.MailSendException,核心异常为jakarta.mail.MessagingException: [EOF]。

已尝试的操作:

  • 切换SMTP端口(587/465)
  • 更换网络环境
  • 关闭安全软件、调整防火墙设置
  • 重装Windows系统
  • 通过AI工具调试

错误栈信息如下:

org.springframework.mail.MailSendException: Mail server connection failed. Failed messages: jakarta.mail.MessagingException: [EOF]; message exception details (1) are:
Failed message 1:
jakarta.mail.MessagingException: [EOF]
    at org.eclipse.angus.mail.smtp.SMTPTransport.issueCommand(SMTPTransport.java:2373)
    at org.eclipse.angus.mail.smtp.SMTPTransport.helo(SMTPTransport.java:1666)
    at org.eclipse.angus.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:735)
    at jakarta.mail.Service.connect(Service.java:345)
    at org.springframework.mail.javamail.JavaMailSenderImpl.connectTransport(JavaMailSenderImpl.java:480)
    at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:399)
    at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:350)
    at org.springframework.mail.javamail.JavaMailSender.send(JavaMailSender.java:101)
    at com.docmall.demo.service.EmailServiceImpl.sendMail(EmailServiceImpl.java:54)
    at com.docmall.demo.controller.EmailController.authcode(EmailController.java:48)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:255)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:188)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:118)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:926)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:831)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1089)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:979)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1014)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:903)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:527)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:885)
    at jakarta.servlet.http.HttpServlet.service(HttpServlet.java:614)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:51)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:100)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:201)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:116)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:175)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:150)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:167)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:90)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:482)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:115)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:93)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:344)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:391)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:63)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:896)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1736)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:52)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1191)
    at org.apache.tomcat.util.threads.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:659)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:63)
    at java.base/java.lang.Thread.run(Thread.java:840)

排查与解决方案

1. 检查Gmail账号安全配置

  • 若开启了两步验证,必须使用应用专用密码替代普通密码登录SMTP;未开启两步验证的账号,需在Gmail后台开启“不太安全的应用访问”。
  • 登录Gmail账号,查看是否有异常登录拦截通知,手动允许当前设备的访问请求。

2. 修正Spring Boot邮件配置

针对Gmail的SMTP服务,确保配置参数与端口匹配:

587端口(STARTTLS模式)

spring.mail.host=smtp.gmail.com
spring.mail.port=587
spring.mail.username=你的Gmail邮箱地址
spring.mail.password=应用专用密码/普通密码
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true

465端口(SSL模式)

spring.mail.host=smtp.gmail.com
spring.mail.port=465
spring.mail.username=你的Gmail邮箱地址
spring.mail.password=应用专用密码/普通密码
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.ssl.enable=true

注意:Spring Boot 3.x依赖Jakarta Mail API,无需额外引入旧版JavaMail依赖,避免版本冲突。

3. 排查系统代理设置

  • 关闭系统全局代理,或在邮件配置中添加代理参数(若必须使用代理):
spring.mail.properties.mail.smtp.proxy.host=代理IP地址
spring.mail.properties.mail.smtp.proxy.port=代理端口

4. 验证SMTP连通性

使用PowerShell测试本地到Gmail服务器的端口连通性:

# 测试587端口
Test-NetConnection smtp.gmail.com -Port 587
# 测试465端口
Test-NetConnection smtp.gmail.com -Port 465

若连接失败,说明网络存在拦截,可尝试使用手机热点等其他网络,或联系网络管理员排查。

5. 开启详细日志定位问题

添加日志配置,获取SMTP交互的详细过程:

logging.level.org.eclipse.angus.mail=DEBUG
logging.level.org.springframework.mail=DEBUG

通过日志查看握手阶段的具体错误,比如证书验证失败、协议不兼容等细节。

6. 检查JDK证书库

确保本地JDK的cacerts证书库包含Gmail的SSL证书,若缺失可手动导入:

keytool -import -alias smtp.gmail.com -keystore $JAVA_HOME/lib/security/cacerts -file 下载的Gmail证书文件路径

默认证书库密码为changeit。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 16:10:53