[英]Spring Boot email sending throws SocketTimeoutException: Read timed out
我已經研究了這個話題幾天了,但我在網上找到的答案都沒有對我有用。
上下文:我有一個 Spring Boot Web 應用程序,它使用 Java Mail API 和 Spring Boot Starter Mail 發送自動電子郵件通知。
它使用帶有 GSuite 帳戶的 GMail SMTP 服務器。 我最近升級為使用 Spring 5.0.6 和 Spring Boot 2.0.2,並且電子郵件發送停止工作。
幾個線索:
已經改變的事情:
以下是 pom.xml 中的相關依賴項:
<!-- https://mvnrepository.com/artifact/javax.mail/javax.mail-api -->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>javax.mail-api</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
這是與 Spring 郵件相關的 application.yml:
spring:
mail:
host: ${FT_MAIL_SMTP_HOST}
port: ${FT_MAIL_SMTP_PORT}
username: ${FT_MAIL_SMTP_USERNAME}
password: ${FT_MAIL_SMTP_PASSWORD}
debug: false
properties:
mail:
smtp:
starttls:
enable: ${FT_MAIL_SMTP_STARTTLS}
required: ${FT_MAIL_SMTP_TLSREQUIRED}
auth: ${FT_MAIL_SMTP_AUTH}
connectiontimeout: ${FT_MAIL_SMTP_CONN_TIMEOUT}
timeout: ${FT_MAIL_SMTP_TIMEOUT}
writetimeout: ${FT_MAIL_SMTP_WRITE_TIMEOUT}
這些變量在環境中定義:
FT_MAIL_SMTP_HOST=smtp.gmail.com
FT_MAIL_SMTP_PORT=587
FT_MAIL_SMTP_USERNAME=myaccount@myapp.com
FT_MAIL_SMTP_PASSWORD=mypassword
FT_MAIL_SMTP_STARTTLS=true
FT_MAIL_SMTP_TLSREQUIRED=true
FT_MAIL_SMTP_AUTH=true
FT_MAIL_SMTP_CONN_TIMEOUT=5000
FT_MAIL_SMTP_TIMEOUT=5000
FT_MAIL_SMTP_WRITE_TIMEOUT=5000
這是用於發送電子郵件的 Spring @Service(未更改):
@Service
public class EmailServiceImpl {
@Autowired
public JavaMailSender emailSender;
@Autowired
private SpringTemplateEngine templateEngine;
@Value("${myapp.mail.from}")
private String fromAddress;
@Value("${myapp.mail.replyto}")
private String replyToAddress;
public void sendTemplatedMessage(String template, String to, String subject, Map<String, Object> model) throws MailException, MessagingException {
sendTemplatedMessage(template, to, fromAddress, replyToAddress, subject, model);
}
public void sendTemplatedMessage(String template, String to, String from, String subject, Map<String, Object> model) throws MailException, MessagingException {
sendTemplatedMessage(template, to, from, replyToAddress, subject, model);
}
private void sendTemplatedMessage(String template, String to, String from, String replyTo, String subject, Map<String, Object> model) throws MailException, MessagingException {
MimeMessage message = emailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message,
MimeMessageHelper.MULTIPART_MODE_MIXED_RELATED,
StandardCharsets.UTF_8.name());
//helper.addAttachment("logo.png", new ClassPathResource("memorynotfound-logo.png"));
Context context = new Context();
context.setVariables(model);
String html = templateEngine.process(template, context);
helper.setTo(to);
helper.setFrom(from);
helper.setReplyTo(from);
helper.setSubject(subject);
helper.setText(html, true);
emailSender.send(message);
}
public void sendSimpleMessage(String to, String from, String subject, String text) {
try {
SimpleMailMessage message = new SimpleMailMessage();
message.setTo(to);
message.setFrom(from);
message.setSubject(subject);
message.setText(text);
emailSender.send(message);
} catch (Exception e) {
e.printStackTrace();
}
}
}
現在這是我嘗試發送電子郵件時遇到的錯誤:
04:42:19.900 [https-jsse-nio-443-exec-3] ERROR c.f.controller.StayController - Could not send Guest confirmation email to gfgorostidi@protonmail.com
org.springframework.mail.MailSendException: Failed to close server connection after message sending; nested exception is javax.mail.MessagingException: Exception reading response;
nested exception is:
java.net.SocketTimeoutException: Read timed out
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:482)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:359)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:354)
at com.myapp.util.EmailServiceImpl.sendTemplatedMessage(EmailServiceImpl.java:61)
at com.myapp.util.EmailServiceImpl.sendTemplatedMessage(EmailServiceImpl.java:35)
at com.myapp.controller.StayController.sendConfirmEmailToGuest(StayController.java:437)
at com.myapp.controller.StayController.saveStay(StayController.java:383)
at com.myapp.controller.StayController.createStay(StayController.java:163)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
......
......
......
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: javax.mail.MessagingException: Exception reading response;
nested exception is:
java.net.SocketTimeoutException: Read timed out
at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2202)
at com.sun.mail.smtp.SMTPTransport.close(SMTPTransport.java:1212)
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:473)
... 104 more
Caused by: java.net.SocketTimeoutException: Read timed out
at java.base/java.net.SocketInputStream.socketRead0(Native Method)
at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:425)
at java.base/sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:65)
at java.base/sun.security.ssl.SSLSocketImpl.bytesInCompletePacket(SSLSocketImpl.java:918)
at java.base/sun.security.ssl.AppInputStream.read(AppInputStream.java:144)
at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:124)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:271)
at com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:89)
at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2182)
... 106 more
org.springframework.mail.MailSendException: Failed to close server connection after message sending; nested exception is javax.mail.MessagingException: Exception reading response;
nested exception is:
java.net.SocketTimeoutException: Read timed out
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:482)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:359)
at org.springframework.mail.javamail.JavaMailSenderImpl.send(JavaMailSenderImpl.java:354)
at com.myapp.util.EmailServiceImpl.sendTemplatedMessage(EmailServiceImpl.java:61)
at com.myapp.util.EmailServiceImpl.sendTemplatedMessage(EmailServiceImpl.java:35)
at com.myapp.controller.StayController.sendConfirmEmailToGuest(StayController.java:437)
at com.myapp.controller.StayController.saveStay(StayController.java:383)
at com.myapp.controller.StayController.createStay(StayController.java:163)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
......
......
......
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1468)
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:844)
Caused by: javax.mail.MessagingException: Exception reading response;
nested exception is:
java.net.SocketTimeoutException: Read timed out
at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2202)
at com.sun.mail.smtp.SMTPTransport.close(SMTPTransport.java:1212)
at org.springframework.mail.javamail.JavaMailSenderImpl.doSend(JavaMailSenderImpl.java:473)
... 104 more
Caused by: java.net.SocketTimeoutException: Read timed out
at java.base/java.net.SocketInputStream.socketRead0(Native Method)
at java.base/java.net.SocketInputStream.socketRead(SocketInputStream.java:116)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:171)
at java.base/java.net.SocketInputStream.read(SocketInputStream.java:141)
at java.base/sun.security.ssl.SSLSocketInputRecord.read(SSLSocketInputRecord.java:425)
at java.base/sun.security.ssl.SSLSocketInputRecord.bytesInCompletePacket(SSLSocketInputRecord.java:65)
at java.base/sun.security.ssl.SSLSocketImpl.bytesInCompletePacket(SSLSocketImpl.java:918)
at java.base/sun.security.ssl.AppInputStream.read(AppInputStream.java:144)
at com.sun.mail.util.TraceInputStream.read(TraceInputStream.java:124)
at java.base/java.io.BufferedInputStream.fill(BufferedInputStream.java:252)
at java.base/java.io.BufferedInputStream.read(BufferedInputStream.java:271)
at com.sun.mail.util.LineInputStream.readLine(LineInputStream.java:89)
at com.sun.mail.smtp.SMTPTransport.readServerResponse(SMTPTransport.java:2182)
... 106 more
我曾嘗試設置不正確的 SMTP 服務器或錯誤的憑據,這導致連接失敗,因此我假設服務器和憑據是正確的,並且在成功連接后發生錯誤。
使用的帳戶尚未達到其限制,因為另一個 VM 使用相同的憑據並毫無問題地發送電子郵件。
我嘗試將“啟動 TLS”設置更改為 false 並改用端口 465,但這也不起作用。
任何幫助表示贊賞! 提前致謝!
在對配置進行了多次反復試驗后,我發現它在配置中需要一個應用程序屬性“spring.mail.protocol”。
我在 application.yml 中添加了線路protocol: smtp
:
spring:
mail:
protocol: smtp
並且解決了讀取超時問題,現在可以正確發送電子郵件。 希望將來可以幫助某人。
我確實遇到了同樣的問題,但我的情況有點不同
我試圖使用石英按計划方式發送
當我不使用 Quartz 時,一切正常,但是使用 Quartz 時它開始出現故障
上述解決方案對我沒有幫助,但為我指明了查看我設置的屬性的方向。
增加連接超時對我有用
從而改變了應用程序屬性
從:
spring.mail.properties.mail.smtp.timeout=3000
到:
spring.mail.properties.mail.smtp.timeout=25000
希望它也適用於其他人
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.