使用 Spring Boot 发送邮件。
依赖
maven 添加以下库:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
配置
spring:
mail:
host: # 比如 <smtp.office365.com>
username: # 比如 <tblsyx@outlook.com>
password: # 密码
port: # 比如 <587>
protocol: # 协议,比如 <smtp>
default-encoding: utf-8
test-connection: true
properties:
mail:
smtp:
connectiontimeout: 10000
timeout: 10000
auth: true
starttls:
enable: true
required: true
socketFactory:
port: 587
class: javax.net.ssl.SSLSocketFactory
代码
注入:
/**
* 邮件发送线程池
*/
private final ExecutorService mailThreadPool;
private final JavaMailSender mailSender;
/**
* 邮件列表
*/
private LinkedBlockingQueue<Email> mailSendQueue;
@Autowired
public EmailService(@Qualifier("mailSendingExecutorService") ExecutorService mailThreadPool,
JavaMailSender mailSender) {
this.mailThreadPool = mailThreadPool;
this.mailSender = mailSender;
}
主要实现:
try {
if (isValidEmailAddres(email.getEmailAddr())) {
log.info("Sending mail to {}", email.getEmailAddr());
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true,
String.valueOf(StandardCharsets.UTF_8));
messageHelper.setFrom("tblsyx@outlook.com");
messageHelper.setTo(email.getEmailAddr());
messageHelper.setSubject("Mail from bolitao.xyz");
messageHelper.setText("<h3>Hello World!</h3>" + email.getContent(), true);
mailSender.send(mimeMessage);
log.info("Sent mail to {} success", email.getEmailAddr());
} else {
String errorContent = String.format("Wrong email address: %s", email.getEmailAddr());
log.error(errorContent);
throw new MessagingException(errorContent);
}
} catch (MessagingException | InterruptedException e) {
log.error("Failed to send email", e);
} catch (Exception e) {
log.error("Failed to send email", e);
}
问题
Outlook 的问题
在测试中,出现以下异常:
2020-12-10 14:47:27.104 ERROR 17816 --- [ mail-pool-4] x.b.java_starter.service.EmailService : Failed to send email
org.springframework.mail.MailSendException: Failed messages: com.sun.mail.smtp.SMTPSendFailedException: 432 4.3.2 STOREDRV.ClientSubmit; sender thread limit exceeded [Hostname=xxx.xxx.prod.outlook.com]
我使用的是微软的 Outlook 帐号,查了下,还真是微软的问题,有发送限制。Changes in message store and throttling for concurrent connections - Exchange | Microsoft Docs:
The service has various limits to prevent abuse and to ensure fair use. An additional limit is being added. Under the new limit, up to three concurrent connections are allowed to send email messages at the same time.
怎么办?上面的文档给出了三个解决办法。我觉得就第三点有用:换别家的,别用 Outlook toC 用作邮件发送服务。