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
相关产品推荐
相关产品推荐

