一、邮件相关知识补充
- SMTP(Simple Mail Transfer Protocol)
即简单邮件传输协议,它是一组用于由源地址到目的地址传送邮件的规则,由它来控制信件的中转方式。SMTP协议属于TCP/IP协议族,它帮助每台计算机在发送或中转信件时找到下一个目的地。通过SMTP协议所指定的服务器,就可以把E-mail寄到收信人的服务器上了,整个过程只要几分钟。SMTP服务器则是遵循SMTP协议的发送邮件服务器,用来发送或中转发出的电子邮件。
在传输邮件过程中使用标准服务端口:25号端口
- SMTP的工作方式
首先发送SMTP在接到用户的邮件请求后,判断此邮件是否为本地邮件,若是直接投送到用户的邮箱,否则向dns查询远端邮件服务器的MX纪录,并建立与远端接收SMTP之间的一个双向传送通道,此后SMTP命令由发送SMTP发出,由接收SMTP接收,而应答则反方面传送。一旦传送通道建立,SMTP发送者发送MAIL命令指明邮件发送者。如果SMTP接收者可以接收邮件则返回OK应答。SMTP发送者再发出RCPT命令确认邮件是否接收到。如果SMTP接收者接收,则返回OK应答;如果不能接收到,则发出拒绝接收应答(但不中止整个邮件操作),双方将如此重复多次。当接收者收到全部邮件后会接收到特别的序列,如果接收者成功处理了邮件,则返回OK应答即可。
- POP3(Post Office Protocol 3)
即邮局协议的第3个版本,它是规定个人计算机如何连接到互联网上的邮件服务器进行收发邮件的协议。它是因特网电子邮件的第一个离线协议标准,POP3协议允许用户从服务器上把邮件存储到本地主机(即自己的计算机)上,同时根据客户端的操作删除或保存在邮件服务器上的邮件,而POP3服务器则是遵循POP3协议的接收邮件服务器,用来接收电子邮件的。POP3协议是TCP/IP协议族中的一员。本协议主要用于支持使用客户端远程管理在服务器上的电子邮件。
POP3使用标准默认端口:110号端口
- IMAP4(Internet Message Access Protocol 4)
交互式数据消息访问协议第四个版本,它与POP3协议一样也是规定个人计算机如何访问互联网上的邮件服务器进行收发邮件的协议,但是IMAP4协议同POP3协议相比更高级。IMAP4协议支持客户机在线或者离线访问并阅读服务器上的邮件,还能交互式的操作服务器上的邮件。IMAP4协议更人性化的地方是不需要像POP3协议那样把邮件下载到本地,用户可以通过客户端直接对服务器上的邮件进行操作(这里的操作是指:在线阅读邮件
在线查看邮件主题 大小 发件地址等信息)。用户还可以在服务器上维护自己邮件目录(维护是指移动 新建 删除 重命名 共享 抓取文本
等操作)。IMAP4协议弥补了POP3协议的很多缺陷。本协议是用于客户机远程访问服务器上电子邮件,它是邮件传输协议新的标准。
IMAP4协议的默认端口:143号端口
IMAP4也支持ASCII码明文传输密码。
二、整合邮件
-
添加依赖
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
-
添加邮箱配置
spring: mail: default-encoding: UTF-8 host: smtp.163.com //邮箱服务器地址 password: xxyyooo //密码 username: [email protected] //用户名
-
编写MailService
package top.xtslife.mail.email; /** * @Author 小涛 * @Create 2019/8/19 9:52 */ public interface MailService { /** * 简单邮件 * @param to * @param subject * @param content */ void sendSimpleMail(String to,String subject,String content); /** * html邮件 * @param to * @param subject * @param content */ void sendHtmlMail(String to, String subject, String content); /** * 发送带附件的邮件 * @param to * @param subject * @param content * @param filePath */ void sendAttachmentsMail(String to, String subject, String content, String filePath); /** * 发送带静态资源的邮件 * @param to * @param subject * @param content * @param rscPath * @param rscId */ void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId); }
-
编写MailSetviceImpl
package top.xtslife.mail.email; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.FileSystemResource; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.mail.javamail.MimeMailMessage; import org.springframework.mail.javamail.MimeMessageHelper; import org.springframework.stereotype.Component; import org.springframework.stereotype.Service; import javax.mail.MessagingException; import javax.mail.internet.MimeMessage; import java.io.File; /** * @Author 小涛 * @Create 2019-08-19 9:40 */ @Component public class MailServiceImpl implements MailService { private final Logger LOGGER = LoggerFactory.getLogger(MailServiceImpl.class); @Autowired private JavaMailSender mailSender; @Value("${spring.mail.username}") private String from; // 简单邮件 public void sendSimpleMail(String to,String subject,String content){ // 创建简单邮件会话类 SimpleMailMessage simpleMailMessage = new SimpleMailMessage(); // 设置发送人 simpleMailMessage.setFrom(from); // 设置接收人 simpleMailMessage.setTo(to); // 设置主题 simpleMailMessage.setSubject(subject); // 设置内容 simpleMailMessage.setText(content); try{ mailSender.send(simpleMailMessage); LOGGER.info("简单邮件已经发送..."); }catch (Exception e){ LOGGER.error("发送简单邮件时异常",e); } } //HTML邮件 @Override public void sendHtmlMail(String to, String subject, String content) { // 为底层JavaMail会话创建一个新的JavaMail MimeMessage MimeMessage mimeMessage = mailSender.createMimeMessage(); try { MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true); mimeMessageHelper.setFrom(from); mimeMessageHelper.setTo(to); mimeMessageHelper.setSubject(subject); mimeMessageHelper.setText(content,true); mailSender.send(mimeMessage); LOGGER.info("html邮件发送成功"); } catch (MessagingException e) { LOGGER.error("发送HTML邮件时发生异常",e); } } // 包含附件的邮件 @Override public void sendAttachmentsMail(String to, String subject, String content, String filePath) { MimeMessage mimeMessage = mailSender.createMimeMessage(); try { MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true); mimeMessageHelper.setFrom(from); mimeMessageHelper.setTo(to); mimeMessageHelper.setSubject(subject); mimeMessageHelper.setText(content,true); FileSystemResource fileSystemResource = new FileSystemResource(new File(filePath)); String fileName = filePath.substring(filePath.lastIndexOf(File.separator)); mimeMessageHelper.addAttachment(fileName,fileSystemResource); mailSender.send(mimeMessage); LOGGER.info("带附件的邮件已经发送"); } catch (MessagingException e) { LOGGER.error("发送带附件的邮件发生异常",e); } } // 包含静态资源的邮件 @Override public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId) { MimeMessage mimeMessage = mailSender.createMimeMessage(); try { MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true); mimeMessageHelper.setFrom(from); mimeMessageHelper.setTo(to); mimeMessageHelper.setSubject(subject); mimeMessageHelper.setText(content,true); FileSystemResource res = new FileSystemResource(new File(rscPath)); mimeMessageHelper.addInline(rscId, res); mailSender.send(mimeMessage); LOGGER.info("嵌入静态资源的邮件已经发送。"); } catch (MessagingException e) { LOGGER.error("发送嵌入静态资源的邮件时发生异常!", e); } } }
-
编写相关测试类
package top.xtslife.mail; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import org.thymeleaf.ITemplateEngine; import org.thymeleaf.context.Context; import top.xtslife.mail.email.MailService; @RunWith(SpringRunner.class) @SpringBootTest public class MailApplicationTests { @Autowired private MailService mailServiceImpl; @Autowired private ITemplateEngine templateEngine; @Test public void testSimpleMail(){ mailServiceImpl.sendSimpleMail("[email protected]","简单邮件测试","myfirst email:hello world"); } @Test public void testHtmlMail(){ String content = "<html>\n" + "<body>\n" + " <h3>hello world ! 这是一封Html邮件!</h3>\n" + "</body>\n" + "</html>"; mailServiceImpl.sendHtmlMail("[email protected]","html邮件测试",content); } @Test public void sendAttachmentsMail(){ String filepath = "E:\\Snipaste_2019-08-15_17-28-01.png"; mailServiceImpl.sendAttachmentsMail("[email protected]","带附件的邮件","这个是我的带附件的邮件",filepath); } @Test public void sendInlineResourceMail() { String rscId = "neo006"; String content="<html><body>这是有图片的邮件:<img src=\'cid:" + rscId + "\' ></body></html>"; String imgPath = "E:\\Snipaste_2019-08-15_17-28-01.png"; mailServiceImpl.sendInlineResourceMail("[email protected]", "主题:这是有图片的邮件", content, imgPath, rscId); } @Test public void sendTemplateMail() { //创建邮件正文 Context context = new Context(); context.setVariable("id", "006"); String emailContent = templateEngine.process("emailTemplate", context); mailServiceImpl.sendHtmlMail("[email protected]","主题:这是模板邮件",emailContent); } }
三、邮件模板
- 添加依赖
<!--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>
- 在 resorces/templates 下创建 模板(例emailTemplate.html)
<!DOCTYPE html> <html lang="zh" xmlns:th="http://www.thymeleaf.org"> <head> <meta charset="UTF-8"/> <title>Title</title> </head> <body> 您好,这是验证邮件,请点击下面的链接完成验证,<br/> <a href="#" th:href="@{ http://www.ityouknow.com/neo/{id}(id=${id}) }">激活账号</a> </body> </html>
注:这里使用的是thymeleaf模板引擎
- 解析模板并发送
@Test public void sendTemplateMail() { //创建邮件正文 Context context = new Context(); context.setVariable("id", "006"); String emailContent = templateEngine.process("emailTemplate", context); mailService.sendHtmlMail("[email protected]","主题:这是模板邮件",emailContent); }
四、其他知识
-
发送失败
因为各种原因,总会有邮件发送失败的情况,比如:邮件发送过于频繁、网络异常等。在出现这种情况的时候,我们一般会考虑重新重试发送邮件,会分为以下几个步骤来实现:
- 1、接收到发送邮件请求,首先记录请求并且入库。
- 2、调用邮件发送接口发送邮件,并且将发送结果记录入库。
- 3、启动定时系统扫描时间段内,未发送成功并且重试次数小于3次的邮件,进行再次发送
-
异步发送
很多时候邮件发送并不是我们主业务必须关注的结果,比如通知类、提醒类的业务可以允许延时或者失败。这个时候可以采用异步的方式来发送邮件,加快主交易执行速度,在实际项目中可以采用MQ发送邮件相关参数,监听到消息队列之后启动发送邮件
- 添加依赖
原文地址:https://www.cnblogs.com/XtsLife/p/11376211.html