Practical guide to diversified email functions, have you learned it?

Preface
In today's digital age, email, as an important means of communication, is widely used in various systems. Whether it is system notifications, user interactions, or file transfers, email plays an indispensable role.
This article will explore how to send text, attachments, HTML, and image-type emails, and add some practical functions on this basis, such as batch sending of emails, dynamic email template rendering, etc., to help developers build more powerful email services.
accomplish
Dependency introduction
<dependencies>
<!-- Spring Boot Web支持,用于后续可能的Web接口开发 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Spring Boot邮件启动器 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!-- JavaMail API -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
</dependency>
<!-- Thymeleaf模板引擎,用于邮件模板渲染 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- 测试依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- Lombok简化代码编写 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
Configuration Information
spring:
mail:
host: smtp.163.com
port: 465
username: your_email@163.com
password: your_password
properties:
mail:
debug: true
smtp:
auth: true
starttls.enable: true
socketFactoryClass: javax.net.ssl.SSLSocketFactory
default-encoding: UTF-8
protocol: smtps
thymeleaf:
prefix: classpath:/templates/
suffix: .html
cache: false
from:
mail:
address: your_email@163.com
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
Please replace your_email@163.com with your actual email address and your_password with your email authorization code (not your login password). If you use another email server, you need to modify the spring.mail.host and other configurations accordingly.
Core code
public interface MailService {
void sendSimpleMail(String to, String subject, String content);
void sendHtmlMail(String to, String subject, String content);
void sendAttachmentsMail(String to, String subject, String content, String filePath);
void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId);
void sendBatchSimpleMail(String[] tos, String subject, String content);
void sendDynamicTemplateMail(String to, String subject, String templateName, Object model);
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
Implementation Class
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import org.yian.service.MailService;
import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.io.File;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
@Service
@Slf4j
public class MailServiceImpl implements MailService {
@Resource
private JavaMailSender mailSender;
@Resource
private TemplateEngine templateEngine;
@Value("${from.mail.address}")
private String from;
@Override
public void sendSimpleMail(String to, String subject, String content) {
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(to);
message.setSubject(subject);
message.setText(content);
try {
mailSender.send(message);
log.info("文本邮件已经发送");
} catch (Exception e) {
log.error("发生发送文本邮件错误!", e);
}
}
@Override
public void sendHtmlMail(String to, String subject, String content) {
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);
mailSender.send(message);
log.info("html邮件发送成功");
} catch (MessagingException e) {
log.error("发生发送html邮件错误!", e);
}
}
@Override
public void sendAttachmentsMail(String to, String subject, String content, String filePath) {
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);
FileSystemResource file = new FileSystemResource(new File(filePath));
String fileName = filePath.substring(filePath.lastIndexOf(File.separator));
helper.addAttachment(fileName, file);
mailSender.send(message);
log.info("带附件的邮件已经发送");
} catch (MessagingException e) {
log.error("发生发送带附件邮件错误!", e);
}
}
@Override
public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId) {
MimeMessage message = mailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content, true);
FileSystemResource res = new FileSystemResource(new File(rscPath));
helper.addInline(rscId, res);
mailSender.send(message);
log.info("嵌入静态图片的邮件已经发送");
} catch (MessagingException e) {
log.error("发生发送嵌入静态图片邮件错误!", e);
}
}
@Override
public void sendBatchSimpleMail(String[] tos, String subject, String content) {
for (String to : tos) {
sendSimpleMail(to, subject, content);
}
log.info("批量文本邮件已发送完成");
}
@Override
public void sendDynamicTemplateMail(String to, String subject, String templateName, Object model) {
Context context = new Context();
if (model instanceof Map) {
context.setVariables((Map<String, Object>) model);
} elseif (model != null) {
Map<String, Object> map = new HashMap<>();
Field[] fields = model.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
try {
map.put(field.getName(), field.get(model));
} catch (IllegalAccessException e) {
log.error("转换对象为Map时出错", e);
}
}
context.setVariables(map);
}
String emailContent = templateEngine.process(templateName, context);
sendHtmlMail(to, subject, emailContent);
log.info("动态模板邮件已发送");
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
Create a userInfoTemplate.html file in the src/main/resources/templates directory (Thymeleaf loads templates from this directory by default). The sample content is as follows:
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>用户信息模板</title>
</head>
<body>
<h1>用户信息</h1>
<p>姓名:<span th:text="${name}"></span></p>
<p>年龄:<span th:text="${age}"></span></p>
</body>
</html>
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
Unit Testing
import cn.example.mail.service.MailService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class MailBootTest {
@Autowired
private MailService mailService;
@Test
public void testSimpleMail() {
mailService.sendSimpleMail("test@example.com", "测试简单文本邮件", "这是一封简单的文本邮件");
}
@Test
public void testHtmlMail() {
String content = "<html><body><h2>hello! 这是一封html邮件!</h2></body></html>";
mailService.sendHtmlMail("test@example.com", "这是html邮件", content);
}
@Test
public void sendAttachmentsMail() {
String filePath = "C:\\example\\attachment.pdf";
mailService.sendAttachmentsMail("test@example.com", "主题:带附件的邮件", "有附件,请查收!", filePath);
}
@Test
public void sendInlineResourceMail() {
String rscId = "exampleImage";
String content = "<html><body>这是有图片的邮件:<img src='cid:" + rscId + "'></body></html>";
String imgPath = "C:\\example\\image.jpg";
mailService.sendInlineResourceMail("test@example.com", "主题:这是有图片的邮件", content, imgPath, rscId);
}
@Test
public void sendBatchSimpleMail() {
String[] tos = {"test1@example.com", "test2@example.com"};
mailService.sendBatchSimpleMail(tos, "批量测试邮件", "这是批量发送的文本邮件");
}
@Test
public void sendDynamicTemplateMail() {
User user = new User("一安", 25);
mailService.sendDynamicTemplateMail("test@example.com", "动态模板邮件测试", "userInfoTemplate", user);
}
// 测试用的用户类
private static class User {
private String name;
private int age;
public User(String name, int age) {
this.name = name;
this.age = age;
}
// 省略getter和setter方法
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
Summarize
In actual projects, the functions of the mail service can be further expanded, for example:
- Send emails asynchronously: Use Spring's asynchronous task mechanism to asynchronously send emails, avoid blocking the main thread, and improve system performance and response speed.
- Email sending status tracking: Through the feedback of the email server or a customized tracking mechanism, the email sending status (such as successful sending, failure, read, etc.) is recorded to facilitate subsequent processing by the system.