本文记录学习在SpringBoot中发送邮件。

一 邮件发送过程

  发送邮件是一个我们在项目中经常会用到的功能,如在用户注册时发送验证码,账户激活等都会用到。完整的一个邮件发送过程主要包含以下几个步骤:

  1 发件人在用户邮件代理上写邮件内容及收件人的邮箱地址;

  2 用户邮件代理根据发件人填写的邮件信息,生成一封符合邮件格式的邮件;

  3 用户邮件代理把邮件发送到发信人的邮件服务器上;

  4 发件人的邮件服务器使用 SMTP 协议把这封邮件发送到收件人的邮件服务器上;

  5 收件人的邮件服务器收到邮件后,把这封邮件放到收件人在这个服务器上的信箱中;

  6 收件人使用用户邮件代理来收取邮件。

二 发送邮件示例

  以前发送邮件时,调用 JavaMail 的相关 API 来开发实现,需要我们自己去组装消息体,代码量比较大,实现起来也不是很容易;Spring 提供的JavaMailSender 对JavaMail的Api做了一定的封装,简化了发邮件的过程。JavaMailSender 提供了强大的邮件发送功能,可支持各种类型的邮件发送。Spring Boot在JavaMailSender 的基础上又做了进一步的封装,让我们的使用更加的简单。

  在pom.xml文件中引入需要得依赖

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>

  在application.properties中配置邮件服务相关信息(测试使用得是QQ邮件服务)

# Email
#邮件默认字符集
spring.mail.default-encoding=UTF-8
#邮件服务地址
spring.mail.host=smtp.qq.com
#邮件服务协议,可以不写(查看源码可知,没有时默认值是smtp )
#spring.mail.protocol=smtp
#端口
spring.mail.port=25
#账号
spring.mail.username=********@qq.com
#密码 使用第三方发送邮件时,需要开通授权,所以此处要写邮箱授权码
spring.mail.password=****************

  完成了上边得配置后,在启动服务得时候,SpringBoot会根据我们得配置,为我们初始化好一个JavaMailSender类供我们调用,我们只需要在要使用得地方注入就可以了。

  定义一个邮件服务接口,提供我们得邮件服务方法,其他业务中用到发邮件功能时,调用找个接口就可以了

public interface EmailSenderService {

    /**
* 发送文本消息
* @param subject 邮件主题
* @param content 邮件内容
* @param to 收件人(可变参数,多个时用逗号隔开)
*/
void sendTextMail(String subject, String content, String... to); }
@Service
public class EmailSenderServiceImpl implements EmailSenderService { @Autowired
private JavaMailSender javaMailSender; //发件人邮箱
@Value("${spring.mail.username}")
private String from; @Override
public void sendTextMail(String subject, String content, String... to) {
SimpleMailMessage mailMessage = new SimpleMailMessage();
mailMessage.setFrom(from);
mailMessage.setTo(to);
mailMessage.setSubject(subject);
mailMessage.setText(content);
mailMessage.setSentDate(new Date());
javaMailSender.send(mailMessage);
}
}

  如上,我们在实现类中注入JavaMailSender后直接调用它send方法就可以完成发邮件。其他业务中用到发邮件业务了,直接调用EmailSenderService 接口得方法即可。我们完全也可以把JavaMailSender直接注入到我们得各个业务模块中去,在发邮件时直接调用JavaMailSender得send方法发邮件。但是还是推荐将邮件发送相关功能独立起来,便于维护。

  上边我们实现了发送一个文本邮件,有时候我们还需要在发送邮件时附带发送附件,这种也是支持的,我们添加接口及实现方法

/**
* 发送带附件邮件
* @param subject 主题
* @param content 内容
* @param filePath 附件得本地路径
* @param fileName 附件名
* @param to 收件人
*/
void sendAttachmentMail(String subject, String content, String filePath, String fileName, String... to);
@Override
public void sendAttachmentMail(String subject, String content, String filePath, String fileName, String... to) {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
try {
MimeMessageHelper helper = new MimeMessageHelper(mimeMessage, true);
helper.setFrom(from);
helper.setTo(to);
helper.setSubject(subject);
helper.setText(content);
//附件
FileSystemResource file = new FileSystemResource(new File(filePath));
helper.addAttachment(fileName, file); javaMailSender.send(mimeMessage);
} catch (MessagingException e) {
e.printStackTrace();
}
}

  如果我们发送邮件时,除了收件人之外,还想让某些人知道即抄送某些人,这种也是支持得,接口及实现方法如下:

/**
* 发送一个邮件并抄送
* @param subject 主题
* @param content 内容
* @param ccList 抄送人(可以有多个)
* @param to 收件人(可以有多个)
*/
void sendTextMail(String subject, String content, List<String> ccList, String... to);
@Override
public void sendTextMail(String subject, String content, List<String> ccList, String... to) {
//收件人地址
InternetAddress[] addressesTo = new InternetAddress[to.length];
if(to != null && to.length>0){
for(int i=0;i<to.length;i++){
InternetAddress addressTo = null;
try {
addressTo = new InternetAddress(to[i]);
addressesTo[i] = addressTo;
} catch (AddressException e) {
e.printStackTrace();
}
}
}
//抄送人地址
InternetAddress[] addressesCc = new InternetAddress[ccList.size()];
if(ccList != null && ccList.size() > 0){
for(int i=0;i<ccList.size();i++){
String ccAdd = ccList.get(i);
InternetAddress address = null;
try {
address = new InternetAddress(ccAdd);
addressesCc[i] = address;
} catch (AddressException e) {
e.printStackTrace();
}
}
} MimeMessagePreparator preparator = new MimeMessagePreparator() {
@Override
public void prepare(MimeMessage mimeMessage) throws Exception {
mimeMessage.setFrom(from);
mimeMessage.setSubject(subject);
mimeMessage.setText(content);
mimeMessage.setRecipients(Message.RecipientType.TO, addressesTo);
mimeMessage.setRecipients(Message.RecipientType.CC, addressesCc);
}
};
javaMailSender.send(preparator);
}

  如上方法就实现了向多人发送邮件并且抄送多人

SpringBoot入门 (十) 发送邮件的更多相关文章

  1. SpringBoot入门 (十四) Security安全控制

    本文记录在SpringBoot使用SpringSecurity进行安全访问控制. 一 什么是Security Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访 ...

  2. SpringBoot入门 (十二) 定时任务

    本文记录在SpringBoot中使用定时任务. 在我们的项目中,经常需要用到定时任务去帮我们做一些事情,比如服务状态监控,业务数据状态的更改等,SpringBoot中实现定时任务有2中方案,一种是自带 ...

  3. SpringBoot入门基础

    目录 SpringBoot入门 (一) HelloWorld. 2 一 什么是springboot 1 二 入门实例... 1 SpringBoot入门 (二) 属性文件读取... 16 一 自定义属 ...

  4. SpringBoot入门系列(十二)统一日志收集

    前面介绍了Spring Boot 异常处理,不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/category/1657780.html. 今 ...

  5. SpringBoot第二十四篇:应用监控之Admin

    作者:追梦1819 原文:https://www.cnblogs.com/yanfei1819/p/11457867.html 版权声明:本文为博主原创文章,转载请附上博文链接! 引言   前一章(S ...

  6. SpringBoot第十二集:度量指标监控与异步调用(2020最新最易懂)

    SpringBoot第十二集:度量指标监控与异步调用(2020最新最易懂) Spring Boot Actuator是spring boot项目一个监控模块,提供了很多原生的端点,包含了对应用系统的自 ...

  7. SpringBoot入门及深入

    一:SpringBoot简介 当前互联网后端开发中,JavaEE占据了主导地位.对JavaEE开发,首选框架是Spring框架.在传统的Spring开发中,需要使用大量的与业务无关的XML配置才能使S ...

  8. Android入门(十二)SQLite事务、升级数据库

    原文链接:http://www.orlion.ga/610/ 一.事务 SQLite支持事务,看一下Android如何使用事务:比如 Book表中的数据都已经很老了,现在准备全部废弃掉替换成新数据,可 ...

  9. SpringBoot入门教程(二)CentOS部署SpringBoot项目从0到1

    在之前的博文<详解intellij idea搭建SpringBoot>介绍了idea搭建SpringBoot的详细过程, 并在<CentOS安装Tomcat>中介绍了Tomca ...

随机推荐

  1. angular2的ngfor ngif指令嵌套

    angular2的ngfor ngif指令嵌套 ng2 结构指令不能直接嵌套使用,可使用<ng-container>标签来包裹指令 示例如下: <ul> <ng-cont ...

  2. HanLP极致简繁转换详细讲解

    HanLP极致简繁转换详细讲解 作者: hankcs(大快高级研究员 hanlp项目负责人) 谈起简繁转换,许多人以为是小意思,按字转换就行了.事实上,汉语历史悠久,地域复杂,发展至今在字符级别存在“ ...

  3. Sql Server Report Service 的部署问题(Reporting Service 2014為什麼不需要IIS就可以運行)

    http://www.cnblogs.com/syfblog/p/4651621.html Sql Server Report Service 的部署问题 近期在研究SSRS部署问题,因为以前也用到过 ...

  4. x230安装黑苹果

    https://forum.51nb.com/forum.php?mod=viewthread&tid=1802786&extra=page%3D1&page=1 下载 主要就 ...

  5. 代码从Polyline读取到的坐标和属性对话框显示的不一样?

    属性窗口中查询的第一个点坐标: 程序输出的各个点坐标: 差这么多? 原来是坐标系的问题,程序查询到的是世界坐标,属性窗口中是当前ucs坐标 Document doc = Application.Doc ...

  6. 黄聪:多个wordpress网站(不同域名)共享用户数据的方法

    WordPress可以自定义用户数据表,这样多个wordpress网站就可以共享用户数据了,有时候这是非常方便的,这些Wordpress站点应该安装在同一个数据库下,数据表前缀各不相同.由于Wordp ...

  7. Xshell里连接VirtualBox里的Centos7

    关闭虚拟机 右键虚拟机->设置->网络,连接方式选择NAT,如下图: 3.在Xshell里连接即可.

  8. ALGO-146_蓝桥杯_算法训练_4-2找公倍数

    AC代码: #include <stdio.h> int main(void) { int i; ; i <= ; i ++) { == && i% == ) { p ...

  9. Android兼容包之MultiDex

    一.MultiDex的产生背景 当Android系统安装一个应用的时候,有一步是对Dex进行优化,这个过程有一个专门的工具来处理,叫DexOpt.DexOpt的执行过程是在第一次加载Dex文件的时候执 ...

  10. Web jsp开发学习——Session使用

    先展示效果:              导包:    在servlet的doget里创建session      在head里显示session     接下来进行注销的命令    点击注销链接到这个 ...