本文记录学习在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. HDU3501——欧拉函数裸题

    给整数N(1 ≤ N ≤ 1000000000),求小于N的与N不互素的所有正整数的和. 思路:1.用欧拉函数求出小于N的与N互素的正整数的个数: 2.若 p 与 N 互素,则 N-p 必与 N 互素 ...

  2. redis 如何查看所有的key

    可以使用KEYS 命令 KEYS pattern 例如, 列出所有的key redis> keys * 列出匹配的key redis>keys apple* 1) apple1 2) ap ...

  3. Hive 特殊分隔符处理

    HIVE特殊分隔符处理 Hive对文件中的分隔符默认情况下只支持单字节分隔符,,默认单字符是\001.当然你也可以在创建表格时指定数据的分割符号.但是如果数据文件中的分隔符是多字符的,如下图: 01| ...

  4. SqlServer :利用快捷键快速查看 字段说明查询及表结构 (小技巧)

    1.自定义4个常用的存储过程: sp_select :select * from sp_helpremark :查表的列,列的类型,备注(这里只查询有备注的列) sp_columns1 : 查表所有的 ...

  5. KC705开发板关于MIG的配置

    KC705开发板关于MIG的配置

  6. PHP代码实现2 [从变量和数据的角度] 1

    PHP代码实现2 [从变量和数据的角度] 1 数据类型 1.静态类型语言,比如:C/Java等,在静态语言类型中,类型的检查是在<编译>(compile-time)确定的, 也就是说在运行 ...

  7. sqlalchemy 或者pysql 连接数据库时支持中文操作

    参数后面带上?charset=utf8就行 engine = create_engine("mysql+pymysql://hrg:123@192.168.80.200:3306/test? ...

  8. Team Foundation Server 2010简体中文版

    文件名称:Team Foundation Server 2010简体中文版 文件大小:1.8 GBhttp://www.google.com/profiles/dedecms.com 下载地址: th ...

  9. 黄聪:JQUERY判断操作CHECKBOX选中、取消选中、反选、第二次无法选中的问题

    用JQuery做CheckBox全选和反选的时候,遇到一个问题.当用JQ控制全选,全取消一次以后,再次点击全选,发现代码变了,但是CheckBox没有处于选中状态. $("#id" ...

  10. ALGO-13_蓝桥杯_算法训练_拦截导弹(贪心,DP)

    问题描述 某国为了防御敌国的导弹袭击,发展出一种导弹拦截系统.但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度.某天,雷达捕捉到敌国的导弹 ...