1.首先,需要在引入mail,freemarker,thymeleaf,velocity等相关的jar包。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>2.2.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-velocity</artifactId>
<version>1.4.7.RELEASE</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
<version>4.4</version>
</dependency>
2.在resources目录下创建templates与img目录,里边分别放了freemarker、thymeleaf、velocity的模板文件与相关的图片与pdf文档等等。
3.在springboot的默认配置文件application.yml中增加freemarker,thymeleaf的相关配置,以及发送邮件需要用到的参数。
spring:
freemarker:
enabled: true
cache: true
charset: UTF-8
content-type: text/html
check-template-location: true
# 其实这里是默认的路径,理论上可以不用写,至于不写行不行请各位自己去尝试了
template-loader-path: classpath:/templates/
mail:
host: smtp.qq.com
protocol: smtp
username: #自己填写
# qq邮箱授权码,自己提前开通SMTP,具体操作请自行前往qq邮箱进行相应的操作即可。
password: xxxxx
thymeleaf:
cache: false
encoding: UTF-8
mode: LEGACYHTML5
# 其实这里是默认的路径,理论上可以不用写,至于不写行不行请各位自己去尝试了
prefix: classpath:/templates/
3.freemarker、thymeleaf与velocity的模板代码截图
有些地方参照了博客:
https://www.cnblogs.com/lovling/p/12761001.html
freemarker的代码
<style type="text/css">
.mail-table {
width: 100%;
border-top: 1px solid #333;
border-left: 1px solid #333;
border-collapse: collapse;
border-spacing: 0;
}
.mail-table tr {
}
.mail-table th {
background: rgb(255, 204, 204);
height: 40px;
border-bottom: 1px solid #333;
border-right: 1px solid #333;
}
.mail-table td {
height: 36px;
text-indent: 14px;
border-bottom: 1px solid #333;
border-right: 1px solid #333;
}
</style>
<h3>${title}</h3>
<table class="mail-table">
<tr>
<th>序号</th>
<th>账号</th>
<th>昵称</th>
</tr>
<#list users as user>
<tr>
<td>${user_index + 1}</td>
<td>${user.realName}</td>
<td>${user.userName}</td>
</tr>
</#list>
</table>
<!-- 图片地址固定为 cid:MailVo的name,此处为为固定写法 -->
<img src="cid:battle-field" alt="img"/>
thymeleaf的模板mail-the.html的代码截图
velocity的模板mail-vm的代码截图
发送邮件service代码
package com.springcloud.my.service.impl;
import com.springcloud.my.entity.MailVo;
import com.springcloud.my.utils.ContentTypeEnum;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.velocity.Template;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.app.VelocityEngine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
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 javax.mail.Address;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.internet.AddressException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.File;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.util.*;
@Service
public class MailSendService {
@Autowired
private JavaMailSender mailSender;
@Value("${spring.mail.username}")
private String fromMailName;
@Autowired
private TemplateEngine templateEngine;
/**
* 发送邮件的方法
* <p>
* 三种收件人模式的解释
* 1,Message.RecipientType.TO 直接接收人
* 2,Message.RecipientType.CC 明抄送收件人
* 3,Message.RecipientType.BCc 暗抄送收件人(不会 被直接收件人 和 明抄送收件人 看见的收件人)
* @param toAddr 收件人
* @param ccAddr 抄送人
* @param subject 邮件标题
* @param html 邮件内容
* @param srcVos 静态资源类
* @param athVos 附件资源类
*/
public void sendMail(String[] toAddr, String[] ccAddr, String subject, String html, List<MailVo> srcVos, List<MailVo> athVos) {
try {
MimeMessage message = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
helper.setFrom(fromMailName);
helper.setSubject(subject);
helper.setText(html, true);
if (toAddr != null && toAddr.length > 0) {
Address[] addresses = getAddresses(toAddr);
message.setRecipients(Message.RecipientType.TO, addresses);
}
if (ccAddr != null && ccAddr.length > 0) {
Address[] addresses = getAddresses(ccAddr);
message.setRecipients(Message.RecipientType.CC, addresses);
}
if (CollectionUtils.isNotEmpty(srcVos)) {
for (MailVo srcVo : srcVos) {
helper.addInline(srcVo.getName(), srcVo.getFile());
}
}
addAttFile(athVos, helper);
mailSender.send(message);
} catch (MessagingException ex) {
throw new RuntimeException(ex.getMessage());
}
}
private Address[] getAddresses(String[] ccAddr) throws AddressException {
Address[] addresses = new Address[ccAddr.length];
for (int i = 0; i < ccAddr.length; i++) {
addresses[i] = new InternetAddress(ccAddr[i]);
}
return addresses;
}
public void sendSimpleMail(Map<String, Object> valueMap, List<MailVo> athVos, List<MailVo> srcVos) {
try {
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
// 设置发件人邮箱
helper.setFrom(fromMailName);
// 设置收件人邮箱
helper.setTo((String[]) valueMap.get("to"));
// 设置邮件标题
helper.setSubject(valueMap.get("title").toString());
// 设置邮件正文
helper.setSubject(valueMap.get("content").toString());
// 添加正文(使用thymeleaf模板)
Context context = new Context();
context.setVariables(valueMap);
String stringContext = templateEngine.process("mail-the", context);
helper.setText(stringContext, true);
//设置静态
if (CollectionUtils.isNotEmpty(athVos)) {
for (MailVo athVo : athVos) {
helper.addInline(athVo.getName(), new FileSystemResource(athVo.getFile()));
}
}
addAttFile(srcVos, helper);
// 发送邮件
mailSender.send(mimeMessage);
} catch (MessagingException e) {
e.printStackTrace();
}
}
public void setMailByVm(Map<String, Object> contentMap) {
MimeMessage mimeMessage = mailSender.createMimeMessage();
//InputStream inputStream = null;
try {
MimeMessageHelper messageHelper = new MimeMessageHelper(mimeMessage, true);
messageHelper.setFrom(fromMailName);
messageHelper.setTo(fromMailName);
messageHelper.setSubject(contentMap.get("content").toString());
Map<String, Object> map = new HashMap<>();
map.put("url", contentMap.get("url"));
map.put("currentDate", contentMap.get("date"));
Properties properties = new Properties();
//从类路径加载模板文件 设置velocity资源加载方式为class
properties.setProperty("resource.loader", "class");
//设置velocity资源加载方式为class时的处理类
properties.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
properties.setProperty(Velocity.ENCODING_DEFAULT, "UTF-8");
properties.setProperty(Velocity.INPUT_ENCODING, "UTF-8");
properties.setProperty(Velocity.OUTPUT_ENCODING, "UTF-8");
properties.setProperty(Velocity.RUNTIME_LOG_LOGSYSTEM_CLASS, "org.apache.velocity.runtime.log.NullLogChute");
//实例化一个VelocityEngine对象
VelocityEngine velocityEngine = new VelocityEngine(properties);
velocityEngine.init();
StringWriter writer = new StringWriter();
VelocityContext velocityContext = new VelocityContext();
velocityContext.put("test", map);
Template template = velocityEngine.getTemplate("templates/mail-vm.vm");
template.merge(velocityContext, writer);
// 用来让text内容以html格式进行展示
messageHelper.setText(writer.toString(), true);
messageHelper.addInline("identifier01", (File) contentMap.get("imgPath"));
File pdfFile = (File) contentMap.get("pdf");
// 添加pdf附件
messageHelper.addAttachment(MimeUtility.encodeWord(pdfFile.getName()), new FileSystemResource(pdfFile), ContentTypeEnum.PDF.getCentType());
// 发送邮件
mailSender.send(mimeMessage);
} catch (MessagingException | UnsupportedEncodingException e) {
e.printStackTrace();
}
}
/**
* 设置附件
*
* @param srcVos 附件集合
* @param helper
* @throws MessagingException
*/
private void addAttFile(List<MailVo> srcVos, MimeMessageHelper helper) throws MessagingException {
if (CollectionUtils.isNotEmpty(srcVos)) {
for (MailVo athVo : srcVos) {
helper.addAttachment(athVo.getName(), athVo.getFile());
}
}
}
}
发送邮件的controller代码
package com.springcloud.my.controller;
import com.springcloud.my.entity.MailVo;
import com.springcloud.my.entity.User;
import com.springcloud.my.service.impl.MailSendService;
import com.springcloud.my.utils.DateUtils;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.util.ResourceUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.*;
/**
* 邮件发送控制器
*
* @Author Administrator
* @Date 2020/6/23/
*/
@RestController
@RequestMapping("/send")
public class SendEmailController {
@Autowired
private MailSendService mailService;
@Autowired
private Configuration configuration;
@RequestMapping("/send")
public ResponseEntity<Object> sendSimpleMail() throws IOException, TemplateException {
Template template = configuration.getTemplate("mail.ftl", "UTF-8");
Map<String, Object> model = new HashMap<>();
List<User> userList = new ArrayList<>();
for (int i = 0; i < 5; i++) {
User user = new User();
user.setRealName("111111" + i);
user.setUserName("22222" + i);
userList.add(user);
}
model.put("title", "只是测试的邮件");
model.put("users", userList);
String[] toAddr = new String[]{"xxxx@qq.com"};
//抄送人的邮件地址,可以不设置
//String[] ccAddr = new String[] {"xxx@qq.com"};
String subject = "测试邮件";
String html = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
List<MailVo> srcVos = new ArrayList<>();
MailVo mailFileSrc = new MailVo();
mailFileSrc.setName("battle-field");
mailFileSrc.setFile(ResourceUtils.getFile("classpath:static/img/test.png"));
srcVos.add(mailFileSrc);
List<MailVo> athVos = new ArrayList<>();
MailVo mailFileAth = new MailVo();
mailFileAth.setName("你的附件.txt");
mailFileAth.setFile(ResourceUtils.getFile("classpath:static/img/msg.txt"));
athVos.add(mailFileAth);
mailService.sendMail(toAddr, null, subject, html, srcVos, athVos);
return ResponseEntity.ok("邮件发送成功");
}
@RequestMapping("/mailByThy")
public String sendMail() throws FileNotFoundException {
MailVo mailVo = new MailVo();
mailVo.setName("test-img");
mailVo.setFile(ResourceUtils.getFile("classpath:static/img/test.png"));
List<MailVo> list = new ArrayList<>();
list.add(mailVo);
Map<String, Object> valueMap = new HashMap<>();
valueMap.put("to", new String[]{"你自己的QQ邮箱"});
valueMap.put("title", "测试邮件标题111");
valueMap.put("content", "测试邮件内容222");
MailVo fileVo = new MailVo();
fileVo.setName("thymeleaf.txt");
fileVo.setFile(ResourceUtils.getFile("classpath:static/img/msg.txt"));
List<MailVo> athVos = new ArrayList<>();
athVos.add(fileVo);
// 调用发送邮件的方法
mailService.sendSimpleMail(valueMap, list, athVos);
return "使用thymeleaf模板发送邮件成功~~~~~";
}
@RequestMapping("/mailByVm")
public String sendMailByVm() throws FileNotFoundException {
long start = System.currentTimeMillis();
Map<String, Object> map = new HashMap<>();
map.put("url", UUID.randomUUID());
map.put("content", "test");
map.put("date", DateUtils.parseDateToStr("yyyy-MM-dd HH:mm:ss", new Date()));
map.put("imgPath", ResourceUtils.getFile("classpath:static/img/test.png"));
map.put("pdf", ResourceUtils.getFile("classpath:static/xxxx.pdf"));
// 调用发送邮件的方法
mailService.setMailByVm(map);
return "使用velocity模板发送邮件成功~~~~~用时:" + (System.currentTimeMillis() - start) + "毫秒";
}
}
4.ContentTypeEnum.PDF.getCentType()请参考我的另一篇博客:https://blog.****.net/l244112311/article/details/106931863,实在不想去,改为application/pdf即可,DateUtils请参考:https://gitee.com/y_project/RuoYi/blob/master/ruoyi-common/src/main/java/com/ruoyi/common/utils/DateUtils.java,其他的应该没啥了。有需要的可以参照上面的代码自己去尝试了。