1.前言
公司有一个老的项目需要做翻新,老项目中的发送邮件是用 SS(struts2)M 来做的基础架构,旧代码量很大也有很多冗余,于是就打算不再将旧代码复制粘贴了,就准备重新搞,这样自己维护起来也方便,代码也干净整洁(不然翻新又有什么意义)。这里记录一下使用MimeMessageHelper 发送邮件的功能。
2.资料
3.代码
引入Maven
<!-- SpringBoot freemarker -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- 邮件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
<!-- javax.mail-->
<dependency>
<groupId>javax.mail</groupId>
<artifactId>mail</artifactId>
<version>1.4.1</version>
</dependency>
application.yml 配置文件
mail:
# host不配置会注入失败
host: smtp.exmail.qq.com
username: info@zhong-XXXh.com #发件人邮箱
password: y2xqkjXXXXXXJ7zY #密码
default-encoding: utf-8
protocol: smtp
properties:
mail:
smtp:
connectiontimeout: 5000
timeout: 3000
writetimeout: 5000
这个是我自己定义的实体类,用来获取配置文件的变量的
@Component
@Data
public class SystemProp {
@Value("${vcuCompanyLocalUrl}")
private String vcuCompanyLocalUrl;
@Value("${appServerUrl}")
private String appServerUrl;
@Value("${wxServerUrl}")
private String wxServerUrl;
}
这个是作为邮件入参的实体类。
@Data
public class SendMailMessage{
// 接收人
private String receptionMail;
// 公司名称
private String companyName;
// 标题
private String emailTitle;
// 验证码
private String code;
// 客户服务信息
private String custServiceInfo;
// 邮件模板
private String templateName;
// 礼品卡名称
private String giftCardName;
// 用户名称
private String userName;
// 地址
private String httpUrlString;
// 用户id
private Long userId;
// 附件
private List<Map<String,String> > attachmentList;
}
!!!我这里是将所有的邮件都封装到一个Service方便注入调用。
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
// 发送邮件的实现类
@Service
public class SendMailServiceImpl implements SendMailService {
private final static Logger log = LoggerFactory.getLogger(SendMailServiceImpl.class);
// 这个是我自己定义的实体类,用来获取配置文件的变量的
@Resource
private SystemProp systemProp;
//注入MailSender
@Resource
private JavaMailSender mailSender;
//发送邮件的模板引擎
@Resource
private FreeMarkerConfigurer configurer;
/**
* 发送邮件
*
* @param sendMailMessage 发送邮件的主题对象 object
*/
@Override
public void sendMessageMail(SendMailMessage sendMailMessage) throws RuntimeException, OperationNotSupportedException {
if (sendMailMessage == null) {
throw new RuntimeException("sendMailMessage can not be empty");
}
if (sendMailMessage.getCompanyName() == null) {
throw new RuntimeException("companyName can not be empty");
}
if (sendMailMessage.getReceptionMail() == null) {
throw new RuntimeException("receptionMail can not be empty");
}
// 定义异常
Exception exception = null;
try {
// 初始化
MimeMessage mimeMessage = mailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
// 上传附件
if (sendMailMessage.getAttachmentList() != null && sendMailMessage.getAttachmentList().size() > 0) {
for (Map<String, String> m : sendMailMessage.getAttachmentList()) {
String filePath = m.get("file");
if (StringUtils.isNotBlank(filePath)) {
File attachFile = new File(filePath);
if (!attachFile.exists()) {
log.error("attchment [" + filePath + "] was not exists, ignore to add to mail");
continue;
}
//携带附件
//携带附件
FileSystemResource file = new FileSystemResource(new File(filePath));
// 获取文件后缀 (这里如果不标注后缀,下载的附件也是没有后缀的!!!)
String fileSuffix = filePath.toLowerCase().substring(filePath.toLowerCase().lastIndexOf(".") + 1);
helper.addAttachment(m.get("fileName")+"."+fileSuffix, file);
}
}
}
// 发件人
helper.setFrom(systemProp.getUserNameFrom());
// 收件人
helper.setTo(InternetAddress.parse(sendMailMessage.getReceptionMail()));
// 标题
helper.setSubject("【" + sendMailMessage.getEmailTitle() + "】");
Map<String, Object> model = new HashMap<>();
// 页面回显,我这里传入的是对象,当然也可以传入Map、List等集合。
model.put("params", sendMailMessage);
model.put("groups",new ArrayList<>());
// 模板
Template template = configurer.getConfiguration().getTemplate(sendMailMessage.getTemplateName());
//赋值后的模板邮件内容
String text = FreeMarkerTemplateUtils.processTemplateIntoString(template, model);
helper.setText(text, true);
mailSender.send(mimeMessage);
} catch (Exception e) {
exception = e;
log.error("send email error -------", e);
throw new RuntimeException("send email error");
}
}
}
这里附上一张图,左侧是文件路径/mail/message.ftl 。 右侧是值回显。
这是一个ftl模板,可能会有回显 list之类的数据,可以参考下面。
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<style>
.content{
margin:0 auto;
font-size: 16px;
width:1200px;
}
h3{
font-size: 16px;
margin: 5px;
}
.table th{
background:#EEEEEE;
font-size:16px;
padding: 5px;
}
.table td{
font-size:16px;
text-align: center;
padding: 5px;
}
</style>
<head>
<body>
<div class="content">
<div>
<h3>Hi ${params.receptionMail!""},</h3>
<p>您在公司宣传品管理平台上提交了新的账户信息,已发给账户管理人核对,将尽快回复您。</p>
<p>您提交的账户信息:</p>
<table>
<tr><td style="width:150px; text-align: right;">邮件: </td><td >${user.email!""}</td></tr>
<tr><td style="width:150px; text-align: right;">部门: </td><td >${user.dept!""}</td></tr>
<tr><td style="width:150px; text-align: right;">成本中心号: </td><td >${user.costCenter!""}</td></tr>
<tr><td style="width:150px; text-align: right;">订单审批人邮箱一: </td><td >${user.approveMail1!""}</td></tr>
<tr><td style="width:150px; text-align: right;">订单审批人邮箱二: </td><td >${user.approveMail2!""}</td></tr>
<tr><td style="width:150px; text-align: right;">订单审批人邮箱三: </td><td >${user.approveMail3!""}</td></tr>
<tr><td style="width:150px; text-align: right;">账户信息更改原因: </td><td >${user.applyMemo!""}</td></tr>
<!-- <tr><td style="width:150px; text-align: right;">账户申请说明: </td><td >${user.regSupplement!""}</td></tr> -->
</table>
// 传入集合
<#if groups?exists>
<div>
<p>申请加入的账户组</p>
<table width="100%" border="0" cellspacing="0" cellpadding="0" class="table JQtableBg">
<thead style="background:lightgrey">
<tr>
<td class="g150">用户组</td>
<td class="g100">账户组管理人</td>
<td class="g250">说明</td>
</tr>
</thead>
<tbody>
<#list groups as group>
<tr>
<td>${group.name!''}</td>
<td>${group.groupEmail!''}</td>
<td>${group.memo!''}</td>
</tr>
</#list>
</tbody>
</table>
</div>
</#if>
<p>如果您有任何疑问或需要什么帮助,请联系平台客服,或平台账户管理人${params.managerEmail},</p>
<p>谢谢,</p>
<p>客服团队</p>
<p><a href="${params.httpUrlString}/login/${params.simpleName}">${params.httpUrlString}/login/${params.simpleName}</a></p>
<p>P.S. 提醒邮件由系统自动发出,请勿回复本邮件。如果有任何疑问,请咨询网站客服,谢谢!</p>
</div>
</div>
</body>
</html>
最后写一个Controller 进行测试
@Autowired
private SendMailService sendMailService;
@RequestMapping(value = "/sendMessage", method = RequestMethod.GET)
public void sendMailMessage() throws Exception {
SendMailMessage sendMailMessage = new SendMailMessage();
sendMailMessage.setCode("小彩虹");
sendMailMessage.setTemplateName("/mail/message.ftl");
sendMailMessage.setCompanyName("小彩虹");
sendMailMessage.setGiftCardName("小彩虹");
sendMailMessage.setReceptionMail("1794XXX8573@qq.com");
sendMailMessage.setCustServiceInfo("小彩虹");
// 上传附件,如果想传入!多个文件!,直接往map的集合中加就行。
List<Map<String,String>> map = new ArrayList<>();
Map<String, String> m = new HashMap<>();
m.put("file", "D:\\项目文件\\M3文件(新)\\M3日常问题处理记录.xlsx");
//!!!!! 一定要有后缀!!!!!!
m.put("fileName", "圣诞节快乐.xlsx");
map.add(m);
sendMailMessage.setAttachmentList(map);
sendMailService.sendMessageMail(sendMailMessage);
}
这样就可以接受到有附件的邮件啦~