1.邮件协议背景知识
1.1 SMTP协议(Simple Mail Transfer Protocol)
SMTP协议,又称简单邮件传输协议,是建立在FTP文件传输服务上的一种邮件服务,SMTP的重要特性之一是其能跨越网络传输邮件,能够在不同的网络中“接力”传输。可实现相同网络处理进程之间的邮件传输,也可通过中继器或网关实现某处理进程与其他网络之间的邮件传输。
1.2 POP3协议(Post Office Protocol)
POP3协议,主要用于支持使用客户端远程管理在服务器上的电子邮件,邮件发送到服务器上,邮件客户端连接邮件服务器,并下载所有未阅读的电子邮件,采用的是一种存储转发的访问模式。一旦邮件发送到客户端,邮件服务器上的邮件将会被删除。
1.3 IMAP协议(Internet Message Access Protocol)
IMAP协议,是由斯坦福大学在1986年的一种邮件获取协议,作用与POP3协议类似。他们的区别在于:使用IMAP协议获取拉取服务器上的邮件后,服务器并不会删除该邮件。
POP允许电子邮件客户端下载服务器上的邮件,但是您在电子邮件客户端的操作(如:移动邮件、标记已读等),这是不会反馈到服务器上的,比如:您通过电子邮件客户端收取了QQ邮箱中的3封邮件并移动到了其他文件夹,这些移动动作是不会反馈到服务器上的,也就是说,QQ邮箱服务器上的这些邮件是没有同时被移动的 。但是IMAP就不同了,客户端的操作都会反馈到服务器上,您对邮件进行的操作(如:移动邮件、标记已读等),服务器上的邮件也会做相应的动作。也就是说,IMAP是“双向”的。同时,IMAP可以只下载邮件的主题,只有当您真正需要的时候,才会下载邮件的所有内容。
1.4 Mime邮件
它是当前广泛应用的一种电子邮件技术规范,在MIME出台之前,使用RFC822只能发送基本的ASCII码文本信息,邮件内容如果要包括二进制文件、声音和动画等,实现起来非常困难。MIME提供了一种可以在邮件中附加多种不同编码文件的方法,弥补了原来的信息格式的不足。实际上不仅仅是邮件编码,MIME经成为HTTP协议标准的一个部分。
2.邮件传输的简单流程
简单大概的描述一下邮件发送的流程,主要分为三部分:
- 客户端将编辑好的邮件使用SMTP协议发送邮件服务器上
- 邮件服务器在不同的网络中“接力”将邮件发送到收件人的邮件服务上
- 收件人使用POP3/IMAP协议下载/操作服务器上的邮件
3.springBoot对JavaMail的支持
Java可以通过操作JavaMail
中的API,实现邮件的发送,缺点是:需要我们自己编辑各种参数,协议和文本等。SpringBoot对起做了封装,只要引入基础的spring-boot-starter-mail
包以来,通过调用其定义的接口JavaMailSender
中的方法,就可以实现邮件的发送,SpringBoot Send Email。下面举几个不同邮件的场景来说明(可以参考Spring 邮件操作):
首先在发送邮件之前,需要配置基础的相关参数:
# 发送邮件的SMTP服务器
spring.mail.host=smtp.163.com
# 发件人邮箱名
spring.mail.username=
# 发件人第三方授权码(不是邮箱登陆密码,可登陆邮箱查看)
spring.mail.password=
# 邮件默认编码格式
spring.mail.default-encoding=UTF-8
3.1 发送简单文本
@Component
public class SimpleTextMailSender {
//获取配置文件发件人地址
@Value("${spring.mail.username}")
private String sender;
//springBoot封装的邮件发送接口
@Resource
private JavaMailSender javaMailSender;
/**
* 发送简单文本邮件
*
* @param to
* @param subject
* @param text
*/
public void senderText(String to, String subject, String text) {
//消息对象
SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
simpleMailMessage.setFrom(sender);
simpleMailMessage.setTo(to);
simpleMailMessage.setSubject(subject);
simpleMailMessage.setText(text);
javaMailSender.send(simpleMailMessage);
}
}
2.发送html邮件
public void sendHtml(String to, String subject, String text) throws MessagingException {
//创建一个MimeMessage(邮件内容支持普通文本,内嵌图片和附件)
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
//MimeMessageHelper - 是一个辅助类,可以用于填充MimeMessage
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
mimeMessageHelper.setFrom(sender);
mimeMessageHelper.setTo(to);
mimeMessageHelper.setSubject(subject);
//ture - 将邮件内容应用为 text/html 类型
//falsef(默认)- 邮件内容应用为text/plain类型
mimeMessageHelper.setText(text, true);
//发送邮件
javaMailSender.send(mimeMessage);
}
3.发送带有附件的邮件
public void sendAttachFileMail(String to, String subject, String text, String filePath) throws MessagingException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
mimeMessageHelper.setFrom(sender);
mimeMessageHelper.setTo(to);
mimeMessageHelper.setSubject(subject);
mimeMessageHelper.setText(text, true);
//读取指定路径的文件
FileSystemResource fileSystemResource = new FileSystemResource(new File(filePath));
String filename = fileSystemResource.getFilename();
//添加附件
mimeMessageHelper.addAttachment(filename, fileSystemResource.getFile());
//发送邮件
javaMailSender.send(mimeMessage);
}
4.发送带有图片的邮件
//发送图片不同的是:需要指定一个图片的唯一id
public void sentImageMail(String to, String subject, String text, String rscPath, String rscId) throws MessagingException {
MimeMessage mimeMessage = javaMailSender.createMimeMessage();
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
mimeMessageHelper.setFrom(sender);
mimeMessageHelper.setTo(to);
mimeMessageHelper.setSubject(subject);
mimeMessageHelper.setText(text, true);
FileSystemResource fileSystemResource = new FileSystemResource(new File(rscPath));
mimeMessageHelper.addInline(rscId, fileSystemResource.getFile());
javaMailSender.send(mimeMessage);
}
测试类:
@Test
public void sendImageMailTest() throws MessagingException {
String path = "/Users/870caffd8ded59e33518010033ac3529.jpg";
String cid = UUID.randomUUID().toString();
String content = "<html><body><img src=\'cid:" + cid + "\'></img></body></html>";
simpleTextMailSender.sentImageMail("xxx.qq.com", "测试发送带图片的邮件", content, path, cid);
}
写在最后
上面的几个例子只是简单演示邮件发送的例子,真实的发送邮件需要考虑好多东西,比如:异常情况的捕获,邮件发送失败的重试,异步发送的邮件等。对于应用与固定场景的邮件发送需求,比如:账户激活,换手机号等,可能结合FreeMark,Thymeleaf等模版引擎,指定一个统一的邮件发送模版。