springboot 邮件发送实践

140 阅读3分钟

大学之道,在明明德。

1 前言

在现代应用中,发送邮件是一个常见的功能,如账户激活、密码重置、通知提醒等。在本文中,我们将展示如何在 Spring Boot 应用中使用 JavaMailSendercommons-email 实现邮件发送。在文中将展示整个邮件发送的开发的文件配置和开发实践。

2 项目配置

首先需要在项目中引入 mail 的依赖,除了集成 springboot 的邮件发送,还引入了一个 apachecommons-email,本文将两种邮件发送方式。

-- springboot 发送邮件 mail 依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
-- apache mail 发送邮件 mail 依赖
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-email</artifactId>
    <version>1.4</version>
</dependency>

添加依赖后,需要在项目中的 application 中添加相关的配置信息,如下图所示:

spring.mail.host=smtp.163.com
spring.mail.port=994
spring.mail.username=mailusername
spring.mail.password=authcode
spring.mail.properties.mail.smtp.auth=true
spring.mail.properties.mail.smtp.starttls.enable=true

需要注意的是这里使用的是163邮箱,usernamepassword 是邮箱地址和相应的 smtp 服务授权码。

如下图所示,即 java mail 实现邮件的发送,这里使用原生的邮件发送代码显得有些臃肿和复杂,和 java 实现 http 调用一样的复杂,因此需要引出另外两种邮件发送方式,即 springboot mailsenderapache mail

// 设置邮件的配置信息
Properties properties = new Properties();
properties.put("mail.smtp.host", SMTP_HOST);
properties.put("mail.smtp.port", SMTP_PORT);
properties.put("mail.smtp.auth", "true");
properties.put("mail.smtp.starttls.enable", "true");
// 针对 mail 设置身份验证器
Authenticator authenticator = new Authenticator() {
    protected PasswordAuthentication getPasswordAuthentication() {
        return new PasswordAuthentication(SMTP_USERNAME, SMTP_PASSWORD);
    }
};
Session session = Session.getInstance(properties, authenticator);
// 创建邮件对象
Message message = new MimeMailMessage(session);
message.setFrom(new InternetAddress(SMTP_USERNAME)); // 设置发件人
message.setSubject("mail subject"); // 设置邮件主题
// 创建邮件正文
MimeMultipart multipart = new MimeMultipart();
MimeBodyPart bodyPart = new MimeBodyPart();
bodyPart.setContent("这是邮件的内容以及内容的格式", "text/html");
multipart.addBodyPart(bodyPart);
// 在邮件中添加附件
MimeBodyPart attachmentPart = new MimeBodyPart();
File attachmentFile = new File("/path/to/20240921.txt"); // 附件文件路径
attachmentPart.attachFile(attachmentFile);
attachmentPart.setFileName(MimeUtility.encodeText(attachmentFile.getName()));
multipart.addBodyPart(attachmentPart);
// 配置邮件的正文和附件
message.setContent(multipart);
// 设置收件人
message.setRecipient(Message.RecipientType.TO, new InternetAddress("receviver@163.com"));
// 发送邮件
Transport.send(message);

3 springboot 邮件发送逻辑

如果发送的是简单邮件,可以使用 JavaMailSender 的方式来发送,具体代码如下图所示:

@Autowired 
private JavaMailSender javaMailSender; 

// 发送简单邮件 to 为接受者的邮箱地址,subject 为邮件的主体,body 为邮件的内容。
public void sendSimpleEmail(String to, String subject, String body) {

    SimpleMailMessage message = new SimpleMailMessage(); 
    message.setTo(to); 
    message.setSubject(subject); 
    message.setText(body); 
    message.setFrom("发送者邮箱"); 
    javaMailSender.send(message); 
}

如果需要发送带附件的邮件,或者邮件的内容是网页,那么 SimpleMailMessage 就不能胜任了,需要使用 MimeMailMessage 来实现,具体的代码如下所示:

MimeMessage mimeMessage = javaMailSender.createMimeMessage(); 
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true, "UTF-8"); 
// 设置邮件的接收者和发送者,邮件的主体和相应的html内容
helper.setTo(to); 
// 设置邮件中的附件信息
helper.addAttachment("附件名称","附件的路径");
helper.setSubject(subject); 
helper.setText(htmlBody, true); 
helper.setFrom("sender@163.com"); 
javaMailSender.send(mimeMessage);

4 apache mail 发送邮件

apache mail 的邮件发送显得相对简单,其邮箱的配置和 springboot 发送邮件的配置一样,这里使用的是 HtmlEmail 的邮件发送方式,采用这样的方式发送邮件,可以发送 html 文本,即可实现 html 的邮件发送,接收者能够看到渲染后的邮件内容。

HtmlEmail htmlEmail = new HtmlEmail();
htmlEmail.setHostName("smtp.163.com"); // 主机号
htmlEmail.setSmtpPort(994); // 端口号
htmlEmail.setAuthentication("username", "password"); //授权码
htmlEmail.setCharset("UTF-8"); // 字符集
htmlEmail.setSSLOnConnect(true);
log.info("mail begin send");
try {
    htmlEmail.setFrom("sender@163.com", "发送者名称"); // 发送方
    htmlEmail.setSubject(title); // 主题
    htmlEmail.addTo("receviver@163.com");  // 接收方
    // 添加附件 设置附件的路径 path, 以及附件的描述信息
    EmailAttachment attachment = new EmailAttachment();
    attachment.setPath(file);
    attachment.setDisposition(EmailAttachment.ATTACHMENT);
    attachment.setDescription(name);
    htmlEmail.attach(attachment);
    htmlEmail.send();  // 邮件发送

} catch (Exception e) {
    log.info("the email to {} is failure", email.toString());
    throw new RuntimeException("send email failure", e);
}

5 总结

邮件的发送,一般是结合定时任务和 spring 事件来异步调用,以实现业务的解耦。通常在邮件发送时,会有异常的情况发生,需要在处理相应的异常情况,做好发送邮件的记录,异常的情况根据不同的业务场景进行重试即可。需要注意的是,不同的 smtp 服务使用的端口不同,对于是否使用 sls 也存在着区别。在本文中,主要介绍了 springboot 项目发送邮件的配置和发送代码的实现,通过以上的方式可以实现 email 邮件的发送,希望在后续的项目开发中能够有所帮助。