邮件基础
我们经常会听到各种各样的邮件协议,比如 SMTP、POP3、IMAP ,那么这些协议有什么作用,有什么区别?我们先来讨论一下这个问题。
SMTP 是一个基于 TCP/IP 的应用层协议,江湖地位有点类似于 HTTP,SMTP 服务器默认监听的端口号为 25 。看到这里,小伙伴们可能会想到既然 SMTP 协议是基于 TCP/IP 的应用层协议,那么我是不是也可以通过 Socket 发送一封邮件呢?回答是肯定的。
生活中我们投递一封邮件要经过如下几个步骤:
-
深圳的小王先将邮件投递到深圳的邮局
-
深圳的邮局将邮件运送到上海的邮局
-
上海的小张来邮局取邮件
这是一个缩减版的生活中邮件发送过程。这三个步骤可以分别对应我们的邮件发送过程,假设从 aaa@qq.com 发送邮件到 111@163.com :
-
aaa@qq.com 先将邮件投递到腾讯的邮件服务器
-
腾讯的邮件服务器将我们的邮件投递到网易的邮件服务器
-
111@163.com 登录网易的邮件服务器查看邮件
邮件投递大致就是这个过程,这个过程就涉及到了多个协议,我们来分别看一下。
SMTP 协议全称为 Simple Mail Transfer Protocol,译作简单邮件传输协议,它定义了邮件客户端软件与 SMTP 服务器之间,以及 SMTP 服务器与 SMTP 服务器之间的通信规则。
也就是说 aaa@qq.com 用户先将邮件投递到腾讯的 SMTP 服务器这个过程就使用了 SMTP 协议,然后腾讯的 SMTP 服务器将邮件投递到网易的 SMTP 服务器这个过程也依然使用了 SMTP 协议,SMTP 服务器就是用来收邮件。
而 POP3 协议全称为 Post Office Protocol ,译作邮局协议,它定义了邮件客户端与 POP3 服务器之间的通信规则,那么该协议在什么场景下会用到呢?当邮件到达网易的 SMTP 服务器之后, 111@163.com 用户需要登录服务器查看邮件,这个时候就该协议就用上了:邮件服务商都会为每一个用户提供专门的邮件存储空间,SMTP 服务器收到邮件之后,就将邮件保存到相应用户的邮件存储空间中,如果用户要读取邮件,就需要通过邮件服务商的 POP3 邮件服务器来完成。
邮件发送
以qq邮箱为例,现在是不允许直接以用户名密码的方式在代码中发送邮件,首先要申请授权码。
以qq邮箱为例,登录qq邮箱后点击上方设置按钮:
然后点击账户选项:
在账户选项中找到开启POP3/SMTP服务选项:
开启成功之后,即可获取一个授权码,将该号码保存好,一会使用。
创建项目
首先导入依赖:
<!--邮件发送依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--下面两个依赖用于html页面构建邮件模板-->
<!--thymeleaf依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!--freemarker依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
配置基本信息:
在application.properties 中配置邮箱的基本信息:
#smtp协议地址
spring.mail.host=smtp.qq.com
#qq邮箱的端口
spring.mail.port=587
#登录qq邮箱的用户名
spring.mail.username=554856818@qq.com
#获取的授权码
spring.mail.password=ajhzobxzhdbkbceh
spring.mail.default-encoding=UTF-8
#配饰 SSL 加密工厂
spring.mail.properties.mail.smtp.scoketFactory.class=javax.net.ssl.SSLSocketFactory
spring.mail.properties.mail.debug=true
上述工作完成后就可以发送邮件了:
发送简单邮件:
简单邮件就是邮件内容只是普通文本:
//springboot提供的发送邮件的模板引擎
@Autowired
JavaMailSender javaMailSender;
@Test
void contextLoads() {
SimpleMailMessage msg = new SimpleMailMessage();
msg.setSubject("测试邮件主题");
msg.setText("测试邮件内容");
//表示邮件从哪里来,例如:1234@qq.com
msg.setFrom("发送邮件的人");
//msg.setCc();表示抄送给那个用户
//msg.setBcc();表示加密抄送
msg.setSentDate(new Date());
//表示邮件要发送给谁:1234@163.com
msg.setTo("接收邮件的人");
javaMailSender.send(msg);
}
执行上述方法就可以发送简单邮件了:
发送带附件的邮件:
@Test
public void test2() throws MessagingException {
//带附件的邮件
MimeMessage message = javaMailSender.createMimeMessage();
//表示邮件中包含附件
MimeMessageHelper helper = new MimeMessageHelper(message,true);
helper.setSubject("测试邮件主题(带附件)");
helper.setText("测试邮件内容(带附件)");
helper.setFrom("发送邮件的人");
helper.setSentDate(new Date());
helper.addAttachment("测试附件.png",new File("C:\\Users\\ideapad\\Desktop\\研究生\\springmvc工作流程.png"));
helper.setTo("接收邮件的人");
javaMailSender.send(message);
}
注意这里在构建邮件对象上和前文有所差异,这里是通过 javaMailSender 来获取一个复杂邮件对象,然后再利用 MimeMessageHelper 对邮件进行配置,MimeMessageHelper 是一个邮件配置的辅助工具类,创建时候的 true 表示构建一个 multipart message 类型的邮件,有了 MimeMessageHelper 之后,我们针对邮件的配置都是由 MimeMessageHelper 来代劳。最后通过 addAttachment 方法来添加一个附件。
发送带图片资源的邮件
图片资源和附件有什么区别呢?图片资源是放在邮件正文中的,即一打开邮件,就能看到图片。不建议采用这种方法(在限制邮件大小的情况下),图片资源放到附件中比较好
@Test
public void test3() throws MessagingException {
//带附件的邮件
MimeMessage message = javaMailSender.createMimeMessage();
//表示邮件中包含附件
MimeMessageHelper helper = new MimeMessageHelper(message,true);
helper.setSubject("测试邮件主题(正文图片)");
helper.setText("测试邮件内容(正文图片)<img src='cid:p01'/>",true);
helper.setFrom("发送邮件的人");
helper.setSentDate(new Date());
helper.addInline("p01",new FileSystemResource(new File("C:\\Users\\ideapad\\Desktop\\研究生\\springmvc工作流程.png")));
helper.setTo("接收邮件的人");
javaMailSender.send(message);
}
这里的邮件 text 是一个 HTML 文本,里边涉及到的图片资源先用一个占位符占着,setText 方法的第二个参数 true 表示第一个参数是一个 HTML 文本。setText 之后,再通过 addInline 方法来添加图片资源
通过上面这些方法就可以发送我们平时的邮件了。