Spring Boot之邮件服务

news/2024/7/24 11:21:42 标签: mail

发送邮件应该是网站的必备功能之一,什么注册验证,忘记密码或者是给用户发送营销信息。最早期的时候我们会使用 JavaMail 相关 api 来写发送邮件的相关代码,后来 Spring 推出了 JavaMailSender 更加简化了邮件发送的过程,在之后 Spring Boot 对此进行了封装就有了现在的 spring-boot-starter-mail ,本章文章的介绍主要来自于此包。

简单使用

1、pom 包配置

pom 包里面添加 spring-boot-starter-mail 包引用

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

2、在 application.yml中添加邮箱配置

  mail:
    host: smtp.qq.com #邮箱服务器地址
    username: 1308207524@qq.com #用户名
    password: hzuedmalmrojhiad  #授权码
    properties:
      mail:
        smtp:
          auth: true
          starttls:
            enable: true
            required: true

mailservice这里只提出实现类">3、编写 mailService

package com.zoo.lion.modules.message.mail.service;

/**
 * @Author: xf
 * @Date: 2019/7/17 16:44
 * @Version 1.0
 */
public interface MailService {
    void sendSimpleMail(String to, String subject, String content);
}
package com.zoo.lion.modules.message.mail.service.impl;

import com.zoo.lion.modules.message.mail.service.MailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

/**
 * @Author: xf
 * @Date: 2019/7/17 16:45
 * @Version 1.0
 */
@Component
@Slf4j
public class MailServiceImpl implements MailService {

    @Resource
    private JavaMailSender mailSender;

    @Override
    public void sendSimpleMail(String to, String subject, String content) {
        SimpleMailMessage message = new SimpleMailMessage();
        String from = "1308207524@qq.com";
        message.setFrom(from);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(content);

        try {
            mailSender.send(message);
            log.info("简单邮件已经发送。");
        } catch (Exception e) {
            log.error("发送简单邮件时发生异常!", e);
        }
    }
}

4、编写 test 类进行测试

package com.zoo.lion.message;

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;

/**
 * @Author: xf
 * @Date: 2019/7/17 16:51
 * @Version 1.0
 */
@RunWith(SpringRunner.class)
@SpringBootTest
public class MailServiceTest {

    @Autowired
    private com.zoo.lion.modules.message.mail.service.MailService MailService;

    @Test
    public void testSimpleMail() {
        MailService.sendSimpleMail("473059536@qq.com","test simple mail"," hello this is simple mail");
    }
}

至此一个简单的文本发送就完成了。

注意:

PO3/SMTP服务必须开启

如何开启--QQ邮箱界面中,上方这里点击设置按钮进入---设置中,这里继续选择这里的账户选项打开-----最下方开启服务这里POP3/SMTP服务右边点击这里开启按钮。然后按照提示就可以开启了

QQ邮箱发送邮件服务器主机名为:smtp.qq.com,必须使用使用SSL(spring.mail.properties.mail.smtp.socketFactory.class=javax.net.ssl.SSLSocketFactory),端口号465或587(spring.mail.port=465)

但是在正常使用的过程中,我们通常在邮件中加入图片或者附件来丰富邮件的内容,下面讲介绍如何使用 Spring Boot 来发送丰富的邮件。

发送 html 格式邮件

其它都不变在 MailService 添加 sendHtmlMail 方法.

    @Override
    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);
            log.info("html邮件发送成功");
        } catch (MessagingException e) {
            log.error("发送html邮件时发生异常!", e);
        }
    }

在测试类中构建 html 内容,测试发送

    @Test
    public void testHtmlMail() {
        String content = "<html>\n" +
                "<body>\n" +
                "    <h3>hello world ! 这是一封Html邮件!</h3>\n" +
                "</body>\n" +
                "</html>";
        MailService.sendHtmlMail("473059536@qq.com", "test simple mail", content);
    }

 

发送带附件的邮件

在 MailService 添加 sendAttachmentsMail 方法.

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 = filePath.substring(filePath.lastIndexOf(File.separator));
        helper.addAttachment(fileName, file);

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

添加多个附件可以使用多条 helper.addAttachment(fileName, file) 

在测试类中添加测试方法

@Test
public void sendAttachmentsMail() {
    String filePath="C:\Users\xiefei\Pictures\ry.png";
    mailService.sendAttachmentsMail("473059536@qq.com", "主题:带附件的邮件", "有附件,请查收!", filePath);
}

 

发送带静态资源的邮件

邮件中的静态资源一般就是指图片,在 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 = "C:\Users\xiefei\Pictures\ry.png";

    mailService.sendInlineResourceMail("473059536@qq.com", "主题:这是有图片的邮件", content, imgPath, rscId);
}

添加多个图片可以使用多条 <img src='cid:" + rscId + "' > 和 helper.addInline(rscId, res) 来实现 

到此所有的邮件发送服务已经完成了。

邮件系统

上面发送邮件的基础服务就这些了,但是如果我们要做成一个邮件系统的话还需要考虑以下几个问题:

邮件模板

我们会经常收到这样的邮件:

尊敬的xxx用户:
              
          恭喜您注册成为xxx网的用户,,同时感谢您对xxx的关注与支持并欢迎您使用xx的产品与服务。
          ...

其中只有 xxx 这个用户名在变化,其它邮件内容均不变,如果每次发送邮件都需要手动拼接的话会不够优雅,并且每次模板的修改都需要改动代码的话也很不方便,因此对于这类邮件需求,都建议做成邮件模板来处理。模板的本质很简单,就是在模板中替换变化的参数,转换为 html 字符串即可,这里以thymeleaf为例来演示。

1、pom 中导入 thymeleaf 的包

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

**2、在 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.afei.com/activation/{id}(id=${id}) }">激活账号</a>
    </body>
</html>

3、解析模板并发送

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

    mailService.sendHtmlMail("473059536@qq.com","主题:这是模板邮件",emailContent);
}

发送失败

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

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

异步发送

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


http://www.niftyadmin.cn/n/1250850.html

相关文章

springboot之MongoDB的简单使用

MongoDB 简介 MongoDB&#xff08;来自于英文单词“Humongous”&#xff0c;中文含义为“庞大”&#xff09;是可以应用于各种规模的企业、各个行业以及各类应用程序的开源数据库。基于分布式文件存储的数据库。由C语言编写。旨在为 WEB 应用提供可扩展的高性能数据存储解决方…

Vue2升级到Vue3到底是不是一个正确的选择?(尤雨溪亲自回复解读)

作者&#xff1a;掘金干货君https://juejin.cn/post/7117525259212816414就在前两天&#xff0c;一篇反对Vue2升级到Vue3的文章在vue官方社区引起了热议。&#xff08;原文链接&#xff1a;Vue 3 was a mistake that we should not repeat[1]&#xff09;这篇文章从实际应用角度…

Spring Boot 之如何测试打包部署

开发阶段 单元测试 在开发阶段的时候最重要的是单元测试了&#xff0c; Spring Boot 对单元测试的支持已经很完善了。 1、在 pom 包中添加 spring-boot-starter-test 包引用 <dependency><groupId>org.springframework.boot</groupId><artifactId>…

[译]尤雨溪: Vite 会取代 vue-cli 吗?

前言最近在逛 Twitter 时&#xff0c;突发奇想去看了一眼尤大的账号&#xff0c;发现了一段有趣的推文&#xff0c;在尤大国内的社交平台账号中(知乎、微博等)并没有发现他发表过类似的话&#xff0c;倒是听过他说会有越来越多的人弃坑 Webpack 用 Vite&#xff0c;还听过有人说…

Spring Boot 小技巧

一些 Spring Boot 小技巧、小知识点 初始化数据 我们在做测试的时候经常需要初始化导入一些数据&#xff0c;如何来处理呢&#xff1f;会有两种选择&#xff0c;一种是使用 Jpa&#xff0c;另外一种是 Spring JDBC 。两种方式各有区别下面来详细介绍。 使用 Jpa 在使用spri…

2022 年 JavaScript 开发工具的生态,你用的过时了吗?

JS 工具领域的变化实在太快&#x1f680;。本文将自底向上地从「编译器」、「打包器」、「包管理器」、「第三方库开发」、「Web 应用开发」这几个方面来盘点 2022 年 JavaScript 开发工具的生态。编译器编译器负责将输入的代码&#xff0c;转换为某种目标的输出格式。本文只关…

解决 Maven 无法下载 fastdfs-client-java 依赖。

因为fastdfs-client-java-1.27-SNAPSHOT.jar这个依赖包在maven中央仓库是没有的。 需要自己编译源码成jar本地安装到maven 的本地仓库&#xff0c;安装完以后就能正常引用了&#xff08;注意&#xff1a;本地必须安装了Maven&#xff0c;并配置好Maven环境变量&#xff09; &…

node_modules 是该好好治一治了

作为前端开发者&#xff0c;大家有没有被 node_modules 困扰过呢&#xff1f;反正我是有。。。因为 npm 特殊的包管理机制&#xff0c;往往一个很小的项目就会携带一个很大的 node_modules 。相信大家都刷到过下面这张图&#xff0c;这就是对前端依赖最大的讽刺了。&#x1f60…