Java邮件发送

  • 基于springboot实现邮件发送
  • 相关版本
  • 下面是相关代码整理
    • 邮件发送接口MailService
    • 邮件发送实现代码MailServiceImpl
    • 封装的邮件实体EmailMsg
    • 邮件模板,.ftl文件
    • 最后一点,邮件发送者配置
    • 完结

基于springboot实现邮件发送

基于spring-boot-starter-mail实现,普通邮件发送无需额外依赖引入,因我所使用功能涉及模板发送,所以还需要引入spring-boot-starter-freemarker依赖。

相关版本

springboot:2.3.2.RELEASE
spring-boot-starter-mail:2.2.0.RELEASE

下面是相关代码整理

有更好的方案或者优化点可以评论指出

邮件发送接口MailService

import com.ai.demo.entity.EmailMsg;
/*** * @author: xs* @date: 2020/9/21 15:10* @description:*/
public interface MailService {/***  发送普通邮件* @param msg*/void sendMail(EmailMsg msg);
}

邮件发送实现代码MailServiceImpl

邮件发送实现类中的DateUtils类为普通的自定义时间工具类,就不贴代码了

import cn.hutool.extra.template.TemplateException;
import com.ai.demo.entity.EmailMsg;
import com.ai.demo.service.MailService;
import com.ai.demo.util.DateUtils;
import freemarker.template.Template;
import freemarker.template.TemplateNotFoundException;
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Date;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import javax.annotation.Resource;
import javax.mail.Address;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
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.springframework.ui.freemarker.FreeMarkerTemplateUtils;
import org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer;/**** @author: xs* @date: 2020/9/21 15:11* @description:*/
@Service
@Slf4j
public class MailServiceImpl implements MailService {@Value("${spring.mail.username}")private String sendFrom;@Resourceprivate JavaMailSender mailSender;@Autowiredprivate FreeMarkerConfigurer configurer;@Overridepublic void sendMail(EmailMsg msg) {log.info("准备发送邮件。。。");try {sendEmailAsync(msg);log.info("邮件发送成功");} catch (Exception e) {log.error("邮件发送失败",e);}}private boolean sendEmailAsync(EmailMsg msg) {// 异步发送,防止等待响应超时new Thread(()-> sendMail1(msg)).start();return true;}private void sendMail1(EmailMsg emailMsg) {try {//使用JavaMail的MimeMessage,支付更加复杂的邮件格式和内容MimeMessage mime = mailSender.createMimeMessage();//创建MimeMessageHelper对象,处理MimeMessage的辅助类MimeMessageHelper helper = new MimeMessageHelper(mime, true, "utf-8");// 设置发件人邮箱Address address = new InternetAddress(sendFrom, emailMsg.getFromName());helper.setFrom((InternetAddress) address);//设置收件人if (StringUtils.isNotBlank(emailMsg.getToEmails())) {String[] to = emailMsg.getToEmails().split(";");helper.setTo(to);}//设置抄送if (StringUtils.isNotBlank(emailMsg.getCcEmails())) {String[] cc = emailMsg.getCcEmails().split(";");helper.setCc(cc);}// 设置邮件主题helper.setSubject(emailMsg.getSubject());// 设置邮件内容:true表示设定html格式if (emailMsg.getContent() != null) {helper.setText(emailMsg.getContent(), true);} else {this.sendWithTemplate(emailMsg, helper);}//设置邮件图片if (emailMsg.getPictures() != null) {this.setAttachmentOrInline(emailMsg, helper, false);}//设置邮件附件if (emailMsg.getAttachments() != null) {this.setAttachmentOrInline(emailMsg, helper, true);}//设置邮件发送时间if (emailMsg.getSendTime() != null) {helper.setSentDate(emailMsg.getSendTime());} else {helper.setSentDate(new Date());}// 发送邮件mailSender.send(mime);log.info("发送了一封邮件<" + emailMsg.getToEmails() + ">,主题为<" + emailMsg.getSubject() + ">,时间为<" + DateUtils.formatDateTime(new Date()) + ">");} catch (Exception e) {log.error("EmailSendManager.sendMail error,cause by  {}", e.getMessage());}}/*** 添加附件或者图片* @param emailMsg email 信息实体* @param helper 用于填充MimeMessage的工具类* @param isAttachment 如果true,添加附件,否则添加图片*/private void setAttachmentOrInline(EmailMsg emailMsg, MimeMessageHelper helper, boolean isAttachment) {Map<String, String> resources;if (isAttachment) {resources = emailMsg.getAttachments();} else {resources = emailMsg.getPictures();}for (Iterator<Entry<String, String>> it = resources.entrySet().iterator(); it.hasNext(); ) {Map.Entry<String, String> entry = it.next();String cid = entry.getKey();String filePath = entry.getValue();File file = new File(filePath);FileSystemResource fileResource = new FileSystemResource(file);try {if (isAttachment) {helper.addAttachment(MimeUtility.encodeWord(cid), fileResource);} else {helper.addInline(MimeUtility.encodeWord(cid), fileResource);}} catch (MessagingException e) {log.info("EmailSendManager.setAttachmentOrInline={}", e);} catch (UnsupportedEncodingException e) {log.info("EmailSendManager.setAttachmentOrInline={}", e);}}}/*** 以thymeleaf为模板发送邮件*/private void sendWithTemplate(EmailMsg emailMsg, MimeMessageHelper helper) {try {Template template = configurer.getConfiguration().getTemplate(emailMsg.getFreemarkerTemplate());String emailText = FreeMarkerTemplateUtils.processTemplateIntoString(template, emailMsg.getModel());helper.setText(emailText, true);} catch (MessagingException e) {log.error("EmailSendManager.sendWithTemplate={}", e);} catch (TemplateNotFoundException e) {log.error("EmailSendManager.sendWithTemplate={}", e);} catch (IOException e) {log.error("EmailSendManager.sendWithTemplate={}", e);} catch (TemplateException e) {log.error("EmailSendManager.sendWithTemplate={}", e);} catch (freemarker.template.TemplateException e) {e.printStackTrace();}}
}

封装的邮件实体EmailMsg

实体中的model,即为要替换的模板参数

import java.io.Serializable;
import java.util.Date;
import java.util.Map;
import lombok.Data;/**** @author xs* @date 2020/9/21 14:35*/
@Data
public class EmailMsg implements Serializable {private static final long serialVersionUID = -808318905357852929L;/*** 收件人邮箱,多个邮箱以“;”分隔*/private String toEmails;/*** 抄送人人邮箱,多个邮箱以“;”分隔*/private String ccEmails;/*** 邮箱标题*/private String subject;/*** 正文内容*/private String content;/*** Thymeleaf模板*/private String freemarkerTemplate;/*** 声明Map对象,并填入用来填充模板文件的键值对*/private Map<String, Object> model;/*** 邮件中的图片,为空时无图片。map中的key为图片ID,value为图片地址*/private Map<String, String> pictures;/*** 邮件中的附件,为空时无附件。map中的key为附件ID,value为附件地址*/private Map<String, String> attachments;/*** 开始时间*/private String startDate;/*** 结束时间*/private String endDate;/*** 发送时间*/private Date sendTime;/*** 1 已发送 2 未发送*/private Integer status;/*** 1 正常 2 定时*/private Integer type;/*** 发件人昵称*/private String fromName;
}

邮件模板,.ftl文件

该文件存放在resources/templates/目录下
模板只需要在封装EmailMsg时封装进去即可,对应字段为freemarkerTemplate
例:

emailMsg.setFreemarkerTemplate(EmailContentEnum.EMAIL_TEMPLATE.getTemplate());

枚举类内容为:

可针对自己想要的模板自定义模板字段

<table border="0" cellpadding="0" cellspacing="0" width="100%"><tbody> <tr><td>模板标题:</td> </tr><tr><td><b>${对应邮件实体中设置的名,下面以产品id为例}</b></td></tr><tr><td></td></tr><tr><td>产品Id:</td></tr><tr><td>${productId}</td></tr><tr><td></td></tr><tr><td>谢谢!</td></tr><tr><td>某某平台</td></tr><tr><td>------------------------------------------------</td></tr><tr><td>这是系统自动发送的邮件, 请勿回复!</td></tr></tbody>
</table>

最后一点,邮件发送者配置

直接看一下吧,这里我使用的是163邮箱,

完结

测试一下

Java邮件发送基于springboot实现相关推荐

  1. java编写两邮件传输,JAVA邮件发送(文字+图片+附件)【源码】

    介绍: 电子邮件协议 电子邮件的在网络中传输和网页一样需要遵从特定的协议,常用的电子邮件协议包括 SMTP,POP3,IMAP.其中邮件的创建和发送只需要用到 SMTP协议,所有本文也只会涉及到SMT ...

  2. java计算机毕业设计基于springboot+vue+elementUI的旅游网站(源码+数据库+Lw文档)

    项目介绍 旅游管理平台采用B/S模式,促进了旅游管理平台的安全.快捷.高效的发展.传统的管理模式还处于手工处理阶段,管理效率极低,随着用户的不断增多,传统基于手工管理模式已经无法满足当前用户需求,随着 ...

  3. java自带发送邮件,成都汇智动力-java邮件发送只需要java自带的mailjar

    原标题:成都汇智动力-java邮件发送只需要java自带的mailjar java邮件发送只需要java自带的mailjar Email email = emailService.queryEmail ...

  4. java计算机毕业设计基于springboot企业人事工资管理系统

    项目介绍 在这个计算机信息时代深处,对于每个公司来说,人事管理的信息化是企业发展的重要组成部分.使用计算机管理人员信息具有传统管理无法比拟的巨大优势.比如:快速查询.管理方便.可靠性高.存储容量大.保 ...

  5. java计算机毕业设计基于springboot 医院急诊挂号系统

    项目介绍 人难免会有生病的时候,尤其是当一些突发情况下,一旦发生一些疾病很可能会危及生命.这时候如果按照常规的方式进行挂号是很浪费时间的一件事情,更重要的是很可能错过最好的治疗机会,所以各大医院基本都 ...

  6. java计算机毕业设计基于springboot+vue+elementUI的口腔管理平台管理系统(前后端分离)

    项目介绍 口腔卫生是关系民生的一个重要问题.口腔健康会直接影响全身的健康,口腔基本常见的有龋齿,牙周炎等问题,而且人类的牙齿只有2次更换周期,一旦牙齿彻底完成更换终生将不再更换,所以越来越多的人开始关 ...

  7. java计算机毕业设计基于springboot人职匹配推荐系统

    项目介绍 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势:对于人职匹配推荐系统当然也不能排除在外,随着网络技术的不断成熟,带动了人职匹配推荐系统,它彻底改变了过 ...

  8. java计算机毕业设计基于springboot小区物业管理系统

    项目介绍 随着科学技术的飞速发展,各行各业都在努力与现代先进技术接轨,通过科技手段提高自身的优势:对于小区物业管理系统当然也不能排除在外,随着网络技术的不断成熟,带动了小区物业管理系统,它彻底改变了过 ...

  9. java计算机毕业设计基于springboot+vue+elementUI的实验室管理系统(前后端分离)

    项目介绍 科技水平一直是体现一个国家强弱的重要标志,而科技的一点诞生地是实验室,如果能够更好的对实验室进行管理是很多实验室管理人员一直研究的一个问题.只有更加科学和合理化的利用实验室才能够更好的让科技 ...

  10. java计算机毕业设计基于springboot健身房课程预约平台

    项目介绍 本健身网站系统是针对目前健身信息交流网站的实际需求,从实际工作出发,对过去的健身网站系统存在的问题进行分析,结合计算机系统的结构.概念.模型.原理.方法,在计算机各种优势的情况下,采用目前最 ...

最新文章

  1. linux AS 5 DNS 配置中的小错误
  2. Problem 61 修改进程的显示名称
  3. 利用MLAI判定未知恶意程序——里面提到ssl恶意加密流检测使用N个payload CNN + 字节分布包长等特征综合判定...
  4. 中午xxx遭受攻击,然后发现C盘空间体积缩小,发现该目录占用1G多,全部是站点
  5. C#.net 支付宝接口
  6. 大数据之HBase教程
  7. mybatis框架执行原理简单实现
  8. 如何让VsCode自动格式化代码?
  9. POJ 2068 NIm (dp博弈,每个人都有特定的取最大值)
  10. 杰·亚伯拉罕的产品营销35种策略完整版
  11. modbus tcp调试助手_wemos D1 arduino项目实战1-TCP协议连接Tlink平台①
  12. 对事件流的小故事理解
  13. 大华平台linux密码,大华指纹锁管理员密码忘了
  14. K8S-Kubeadm的安装及原理
  15. 安全邮箱怎么注册?邮箱地址是什么?怎么写?快速了解tomvip邮箱
  16. html5游戏编程核心技术与实战目录
  17. python5.网络爬虫
  18. vue实践学习——keep-alive属性及生命周期
  19. 特大通知!!!CSDN和简书博客以后同步更新
  20. 嵌入式系统主要应用于哪些行业中?

热门文章

  1. [转]Flixel只能用于Flex吗?
  2. 系列教程|Apache Doris ODBC 外表使用指南(一)
  3. 关于显存位宽、显存带宽和显存容量的理解
  4. adb 详细使用文档
  5. python 入侵服务器_一个入侵iis服务器的简单案例
  6. Linux下限制带宽的方法
  7. 个人备案网站不能做博客了?
  8. NTRIP传输相关,上篇SNIP NTRIP Caster学习笔记扫盲补充
  9. 采样频率、采样点数、频率分辨率
  10. CSDN博客专家申请的条件及规则