spring boot学习(08):邮件

前言

发送邮件是网站的必备功能之一,常用场景,用户注册验证、忘记密码、或者发送营销信息。最早期JavaMail相关API 来写发送邮件的相关代码,后来Spring 推出了 JavaMailSender 简化了邮件发送代码的编写。参考:java和spring环境发送邮件

spring boot 在 JavaMailSender 的基础上又进行了封装,就有了现在的 spring-boot-starter-mail,让邮件发送的业务更加简洁和完善。

Spring 对邮件的支持

Spring 的 JavaMailSenderImpl 提供了强大的邮件发送功能,可发送普通文本邮件、带附件邮件、HTML 格式邮件、带图片邮件,设置发送内容编码格式、设置发送人的显示名称。

JavaMail API 按其功能划分通常可分为如下三大类。

  • Message 类 :创建和解析邮件的核心 API,用于创建一封邮件,可以设置发件人、收件人、邮件主题、正文信息、发送时间等信息。
  • Transport 类:发送邮件的核心 API 类。
  • Store 类:接收邮件的核心API类。

邮件相关协议内容如下。

  • SMTP 协议:发送邮件协议;
  • POP3 协议:获取邮件协议;
  • IMAP:接收信息的高级协议;
  • MIME:邮件拓展内容格式:信息格式,附件格式。

演示简单使用

1.添加依赖

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

2.在 application.properties 中添加邮箱配置,不同的邮箱参数稍有不同,下面列举几个常用邮箱配置。

163 邮箱配置:

spring.mail.host=smtp.163.com //邮箱服务器地址
spring.mail.username=xxx@oo.com //用户名
spring.mail.password=xxyyooo    //密码
spring.mail.default-encoding=UTF-8

//超时时间,可选
spring.mail.properties.mail.smtp.connectiontimeout=5000  
spring.mail.properties.mail.smtp.timeout=3000
spring.mail.properties.mail.smtp.writetimeout=5000

126邮箱配置:

spring.mail.host=smtp.126.com
spring.mail.username=yourEmail@126.com
spring.mail.password=yourPassword
spring.mail.default-encoding=UTF-8

qq 邮箱配置如下:

spring.mail.host=smtp.qq.com
spring.mail.username=yourEmail@qq.com
spring.mail.password=yourPassword
spring.mail.default-encoding=UTF-8

注意:qq邮箱测试时需要将 spring.mail.username 和 spring.mail.password 改成自己邮箱对应的登录名和密码,这里的密码不是邮箱的登录密码,是开启 POP3 之后设置的客户端授权密码。

JavaMailSender

Spirng 已经帮我们内置了 JavaMailSender,直接在项目中引用即可。我们封装一个 MailService 类来实现普通的邮件发送方法。
MailService:为封装的邮件类 接口

@Component
public class MailServiceImpl implements MailService{

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private JavaMailSender mailSender;

    @Value("${spring.mail.username}")
    private String from;

    @Override
    public void sendSimpleMail(String to, String subject, String content) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(from);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(content);
        try {
            mailSender.send(message);
            logger.info("简单邮件已经发送。");
        } catch (Exception e) {
            logger.error("发送简单邮件时发生异常!", e);
        }

    }
}

简单邮件抄送使用:message.copyTo(copyTo) 来实现。

测试即可

富文本邮件

日常工作中,简单的邮件是不能满足需求的,下面介绍富文本邮件的发送。

发送 HTML 格式邮件

public void sendHtmlMail(String to, String subject, String content) {
    MimeMessage message = mailSender.createMimeMessage();

    try {
        //true 表示需要创建一个 multipart message
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(content, true);

        mailSender.send(message);
        logger.info("html邮件发送成功");
    } catch (MessagingException e) {
        logger.error("发送html邮件时发生异常!", e);
    }
}

富文本邮件抄送使用:helper.addCc(cc) 来实现。

测试

@Test
public void testHtmlMail() throws Exception {
    String content="<html>\n" +
            "<body>\n" +
            "    <h3>hello girl! 这是一封html邮件!</h3>\n" +
            "</body>\n" +
            "</html>";
    mailService.sendHtmlMail("[email protected]","这html邮件",content);
}

发送带附件的邮件

public void sendAttachmentsMail(String to, String subject, String content, String filePath){
    MimeMessage message = mailSender.createMimeMessage();

    try {
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(content, true);

        FileSystemResource file = new FileSystemResource(new File(filePath));
        String fileName = file.getFilename();
        helper.addAttachment(fileName, file);
        //helper.addAttachment("test"+fileName, file);
        //添加多个附件可以使用多条 helper.addAttachment(fileName, file)。


        mailSender.send(message);
        logger.info("带附件的邮件已经发送。");
    } catch (MessagingException e) {
        logger.error("发送带附件的邮件时发生异常!", e);
    }
}

测试:

@Test
public void sendAttachmentsMail() {
    String filePath="d:\\图片\\test.jpg";
    mailService.sendAttachmentsMail("[email protected]", "主题:附件", "有附件,请查收!", filePath);
}

附件可以是图片、压缩包、Word 等任何文件,但是邮件厂商一般都会对附件大小有限制,太大的附件建议使用网盘上传后,在邮件中给出链接。

静态资源邮件

邮件中的静态资源一般就是指图片,在 MailService 添加 sendAttachmentsMail 方法。

public void sendInlineResourceMail(String to, String subject, String content, String rscPath, String rscId){
    MimeMessage message = mailSender.createMimeMessage();

    try {
        MimeMessageHelper helper = new MimeMessageHelper(message, true);
        helper.setFrom(from);
        helper.setTo(to);
        helper.setSubject(subject);
        helper.setText(content, true);

        FileSystemResource res = new FileSystemResource(new File(rscPath));
        helper.addInline(rscId, res);

        mailSender.send(message);
        logger.info("嵌入静态资源的邮件已经发送。");
    } catch (MessagingException e) {
        logger.error("发送嵌入静态资源的邮件时发生异常!", e);
    }
}

测试:

@Test
public void sendInlineResourceMail() {
    String rscId = "neo006";
    String content="<html><body>这是有图片的邮件:<img src=\'cid:" + rscId + "\' ></body></html>";
    String imgPath = "d:\\图片\\weixin.jpg";

    mailService.sendInlineResourceMail("[email protected]", "主题:图片邮件", content, imgPath, rscId);
}

邮件系统

以上是邮件服务的基础,但是实际项目中,我们通常使用邮件模板,在模板中替换参数。

在 resorces/templates 下创建 emailTemplate.html

<!DOCTYPE html>
<html lang="zh" xmlns:th="http://www.thymeleaf.org">
    <head>
        <meta charset="UTF-8"/>
        <title>邮件模板</title>
    </head>
    <body>
        您好,感谢您的注册,这是一封验证邮件,请点击下面的链接完成注册,感谢您的支持<br/>
        <a href="#" th:href="@{http://www.******.com/register/{id}(id=${id}) }">激活账号</a>
    </body>
</html>

发送的过程中会根据传入的 id 值来替换链接中的 {id}。

测试,解析模板并测试

@Autowired
private TemplateEngine templateEngine;

@Test
public void sendTemplateMail() {
    //创建邮件正文
    Context context = new Context();
    context.setVariable("id", "006");
    String emailContent = templateEngine.process("emailTemplate", context);

    mailService.sendHtmlMail("[email protected]","主题:这是模板邮件",emailContent);
}

发送失败
因为各种原因,总会有邮件发送失败的情况,如邮件发送过于频繁、网络异常等。在出现这种情况的时候,我们一般会考虑重新重试发送邮件,会分为以下几个步骤来实现:

  • 接收到发送邮件请求,首先记录请求并且入库。
  • 调用邮件发送接口发送邮件,并且将发送结果记录入库。
  • 启动定时系统扫描时间段内,未发送成功并且重试次数小于 3 次的邮件,进行再次发送。

异步发送

很多时候邮件发送并不是我们主业务必须关注的结果,比如通知类、提醒类的业务可以允许延时或者失败。这个时候可以采用异步的方式来发送邮件,加快主交易执行速度,在实际项目中可以采用 MQ 发送邮件相关参数,监听到消息队列之后启动发送邮件。

猜你喜欢

转载自blog.csdn.net/weixin_41555736/article/details/81060582
今日推荐