公司有一个老的项目需要做翻新,老项目中的发送邮件是用 SS(struts2)M 来做的基础架构,旧代码量很大也有很多冗余,于是就打算不再将旧代码复制粘贴了,就准备重新搞,这样自己维护起来也方便,代码也干净整洁(不然翻新又有什么意义)。这里记录一下使用MimeMessageHelper 发送邮件的功能。
这里提供一下Spring Mail的官网 ——>
引入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); }
这样就可以接受到有附件的邮件啦~