本章目标
整合JavaMail发送邮件,结果展示在文档末尾。
搭建项目
build.gradle依赖
implementation 'org.springframework.boot:spring-boot-starter-mail'
implementation 'org.springframework.boot:spring-boot-starter-web'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
application.yml配置
spring:
mail:
properties:
mail:
smtp:
connectiontimeout: 5000
timeout: 3000
writetimeout: 5000
host: smtp.126.com
protocol: smtp
port: 25
username: 邮箱登录账号,如XXX@126.com
password: 邮箱授权码
- host: 不同的邮箱对应的host不同,126邮箱为smtp.126.com
- username: 发件箱邮箱登录账号
- password: 邮箱授权码,如何获取不同邮箱的授权码可自行百度
Tips:Springboot项目启动时,会根据application.yml中的mail配置实例化JavaMailSenderImpl实例mailSender,在使用mailSender时可以通过@Autowired直接注入。
编写SpringTool工具类
@Component
public class SpringTool implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
public static <T> T getBean(String beanName, Class<T> clazz) {
return applicationContext.getBean(beanName, clazz);
}
public static Object getBean(String beanName) {
return getBean(beanName, null);
}
}
SpringTool工具类主要根据beanName获取对应的对象
编写MailUtil类
public class MailUtil {
private static JavaMailSenderImpl mailSender = SpringTool.getBean("mailSender", JavaMailSenderImpl.class);
@RequiredArgsConstructor
static class MimeMessageHelperBuilder {
private final MimeMessage message;
/**
* 是否带附件 发送带附件和html格式的右键时必须为true
*/
private final boolean multipart;
/**
* 收件人
*/
private String to;
/**
* 右键主题
*/
private String subject;
/**
* 右键内容
*/
private String text;
/**
* 是否html格式的邮件
*/
private boolean html;
MimeMessageHelperBuilder to(String to) {
this.to = to;
return this;
}
MimeMessageHelperBuilder subject(String subject) {
this.subject = subject;
return this;
}
MimeMessageHelperBuilder text(String text) {
this.text = text;
return this;
}
MimeMessageHelperBuilder html(boolean html) {
this.html = html;
return this;
}
MimeMessageHelper build() throws MessagingException {
MimeMessageHelper helper = new MimeMessageHelper(message, multipart);
helper.setFrom(mailSender.getUsername());
helper.setTo(to);
helper.setText(text, html);
helper.setSubject(subject);
return helper;
}
}
/**
* 发送普通文本邮件
* @param to 收件人
* @param subject 邮件标题
* @param text 邮件正文
* @throws MessagingException
*/
public static void setTextMail(String to, String subject, String text) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelperBuilder builder = new MimeMessageHelperBuilder(message, false);
MimeMessageHelper helper = builder.to(to).subject(subject).text(text).build();
sendMail(message);
}
/**
* 发送带附件的邮件
* @param to 收件人
* @param subject 邮件标题
* @param text 邮件正文
* @param attachmentNamePathMap 附件名和附件路径组成的map
* @throws MessagingException
*/
public static void sendAttachmentMail(String to, String subject, String text, Map<String, String> attachmentNamePathMap) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelperBuilder builder = new MimeMessageHelperBuilder(message, true);
MimeMessageHelper helper = builder.to(to).subject(subject).text(text).build();
/**
* 组装附件信息
*/
attachmentNamePathMap.forEach((n, p) -> {
FileSystemResource file = new FileSystemResource(new File(p));
try {
helper.addAttachment(n, file);
} catch (MessagingException e) {
e.printStackTrace();
}
});
sendMail(message);
}
/**
* 发送html格式的邮件
* @param to 收件人
* @param subject 邮件标题
* @param htmlText html文档
* @param inlineNamePathMap src名及路径对应的map
* @throws MessagingException
*/
public static void senHtmlMail(String to, String subject, String htmlText, Map<String, String> inlineNamePathMap) throws MessagingException {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelperBuilder builder = new MimeMessageHelperBuilder(message, true);
MimeMessageHelper helper = builder.to(to).subject(subject).text(htmlText).html(true).build();
/**
* 组装html里img标签的src
*/
inlineNamePathMap.forEach((n, p) -> {
FileSystemResource file = new FileSystemResource(new File(p));
try {
helper.addInline(n, file);
} catch (MessagingException e) {
e.printStackTrace();
}
});
sendMail(message);
}
private static void sendMail(MimeMessage message) {
mailSender.send(message);
}
}
编写单元测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class Chapter04ApplicationTests {
@Test
public void testSendTextMail() throws MessagingException {
MailUtil.setTextMail("***收件人邮箱***", "Text Mail", "测试JavaMail的Text mail");
}
@Test
public void testSendAttachmentMail() throws MessagingException {
Map<String, String> attachmentNamePathMap = new HashMap<>();
attachmentNamePathMap.put("mysql-apt-config_0.8.12-1_all.deb", "/home/bobyco/Downloads/mysql-apt-config_0.8.12-1_all.deb");
attachmentNamePathMap.put("desktop.jpg", "/home/bobyco/Pictures/desktop.jpg");
attachmentNamePathMap.put("Paper_Architecture_by_Dmitri_Popov.jpg", "/home/bobyco/Pictures/Paper_Architecture_by_Dmitri_Popov.jpg");
MailUtil.sendAttachmentMail("***收件人邮箱***", "Text Mail", "测试JavaMail发送带附件的邮件", attachmentNamePathMap);
}
@Test
public void testSendHtmlMail() throws IOException, TemplateException, MessagingException {
Map<String, String> inlineNamePathMap = new HashMap<>();
inlineNamePathMap.put("desktop", "/home/bobyco/Pictures/desktop.jpg");
StringBuffer s = new StringBuffer();
s.append("<html>")
.append("<head>")
.append("<title>Welcome!</title>")
.append("</head>")
.append("<body>")
.append("<h1>Welcome JavaMail!</h1>")
.append("<p>Our latest product:<a href=\"http://baidu.com\"><img src=\"cid:desktop\" alt=\"\"></a></p>")
.append("</body>")
.append("</html>");
MailUtil.senHtmlMail("***收件人邮箱***", "测试发送html格式的右键", s.toString(), inlineNamePathMap);
}
@Test
public void contextLoads() {
}
}
整合FreeMarker,使用FreeMarker模板创建邮件内容
添加FreeMarker依赖
implementation 'org.springframework.boot:spring-boot-starter-freemarker'
在application.yml添加FreeMarker配置
freemarker:
template-loader-path: classpath:/templates/mail/
Tips: Springboot项目启动时,会自动初始化id为freeMarkerConfiguration的freemarker.template.Configuration对象,在使用freeMarkerConfiguration时通过SpringTool获取或使用@Autowired注入都可!
在MailUtil中添加sendTemplateMail方法
private static Configuration cfg = SpringTool.getBean("freeMarkerConfiguration", Configuration.class);
/**
* 使用FreeMarker模板创建邮件内容
* @param to 收件人邮箱
* @param subject 邮件标题
* @param templatePath 模板路径
* @param dataModel 模板对应的数据
* @param inlineNamePathMap src名及路径对应的map
* @throws IOException
* @throws TemplateException
* @throws MessagingException
*/
public static void sendTemplateMail(String to, String subject, String templatePath, Map dataModel, Map<String, String> inlineNamePathMap) throws IOException, TemplateException, MessagingException {
Template temp = cfg.getTemplate(templatePath);
String emailContent = FreeMarkerTemplateUtils.processTemplateIntoString(temp, dataModel);
senHtmlMail(to, subject, emailContent, inlineNamePathMap);
}
在resources/templates/mail路径下编写MailHtmlTemplate.ftl文件
<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>${title}!</h1>
<p>Our latest product:<a href="http://baidu.com"><img src="cid:desktop" alt=""></a></p>
</body>
</html>
编写单元测试
@Test
public void testSendTemplateMail() throws TemplateException, IOException, MessagingException {
Map<String, String> inlineNamePathMap = new HashMap<>();
inlineNamePathMap.put("desktop", "/home/bobyco/Pictures/desktop.jpg");
Map dataModel = new HashMap();
dataModel.put("title", "Welcome JavaMail Creating Email Content by Using a Templating Library!");
MailUtil.sendTemplateMail("***收件人邮箱***", "测试发送使用模板创建正文的邮件", "MailHtmlTemplate.ftl", dataModel, inlineNamePathMap);
}
结果预览
Tips: 如果在邮件里查看不到图片,请在电脑网页版邮箱中设置图片可见,即可浏览到图片!
模板邮件.png
html格式邮件.png
带附件的邮件.png
普通文本邮件.png
源码路径
本文源码地址:https://gitee.com/bobyco/sprintboot2_note_source/tree/master/chapter04
end
网友评论