使用 Spring Boot 开发邮件系统

news2024/11/16 7:38:29

文章目录

  • 使用 Spring Boot 开发邮件系统
    • 邮件发送流程
    • 简单使用
      • 第 1 步:pom 包配置
      • 第 2 步:配置文件
        • 163 邮箱配置
        • 126 邮箱配置
        • QQ 邮箱配置如下:
        • 开启 POP 3 / SMTP 服务、IMAP / SMTP 服务
        • 开通设置客户端授权密码
      • 第 3 步:文本邮件发送
      • 第 4 步:编写 test 类进行测试
    • 富文本邮件
      • 发送 HTML 格式邮件
      • 发送带附件的邮件
      • 发送带静态资源的邮件

使用 Spring Boot 开发邮件系统

邮件发送流程

mail_01

  • 发信人在用户代理上编辑邮件,并写清楚收件人的邮箱地址;

  • 用户代理根据发信人编辑的信息,生成一封符合邮件格式的邮件;

  • 用户代理把邮件发送到发信人的邮件服务器上,邮件服务器上面有一个缓冲队列列,发送到邮件服务器上面的邮件都会加入到缓冲队列中,等待邮件服务器上的 SMTP 客户端进行行发送;

  • 发信人的邮件服务器使用 SMTP 协议把这封邮件发送到收件人的邮件服务器上;

  • 收件人的邮件服务器收到邮件后,把这封邮件放到收件人在这个服务器上的信箱中;

  • 收件人使用用户代理来收取邮件,首先用户代理使用 POP3 协议来连接收件人人所在的邮件服务器,身份验证成功后,用户代理就可以把邮件服务器上面的收件人人邮箱里面的邮件读取出来,并展示给收件人。

这就是邮件发送的一个完整流程。

简单来说,邮件的接收发送类似 Git 中的 push 和 pull,是分开的两个操作。并且 push 和 pull 使用的是不同的协议:push 使用的是 SMTP 协议;pull 使用的是 POP3 协议。

简单使用

最早期的时候使用 JavaMail 的相关 API 来开发,需要自己去封装消息体,代码量比较庞大;后来 Spring 推出了 JavaMailSender 来简化邮件发送过程,JavaMailSender 提供了强大的邮件发送功能,可支持各种类型的邮件发送。

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

第 1 步:pom 包配置

<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=xxx        // 密码
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=xxx@126.com
spring.mail.password=xxx
spring.mail.default-encoding=UTF-8
QQ 邮箱配置如下:
spring.mail.host=smtp.qq.com
spring.mail.username=xxx@qq.com
spring.mail.password=xxx
spring.mail.default-encoding=UTF-8

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

这里以 126 邮件举例,有两个地方需要在邮箱中设置。

开启 POP 3 / SMTP 服务、IMAP / SMTP 服务

mail_02

图片下方会有 SMTP 等相关信息的配置提示。

开通设置客户端授权密码

mail_03

设置客户端授权密码一般需求手机验证码验证。

第 3 步:文本邮件发送

Spring 已经帮我们内置了 JavaMailSender,直接在项目中引用即可,封装一个 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) 来实现。

  • from,即为邮件发送者,一般设置在配置文件中
  • to,邮件接收者,此参数可以为数组,同时发送多人
  • subject,邮件主题
  • content,邮件的主体

邮件发送者 from 一般采用固定的形式写到配置文件中。

第 4 步:编写 test 类进行测试

@RunWith(SpringRunner.class)
@Spring BootTest
public class MailServiceTest {

    @Autowired
    private MailService MailService;

    @Test
    public void testSimpleMail() throws Exception {
        mailService.sendSimpleMail("test@126.com", "这是一封简单邮件", "大家好,这是我的第一封邮件!");
    }
}

稍微等待几秒,就可以在邮箱中找到此邮件内容了。

富文本邮件

在日常使用的过程中,我们通常在邮件中加入图片或者附件来丰富邮件的内容。

发送 HTML 格式邮件

邮件发送支持以 HTML 语法去构建自定义的邮件格式,Spring Boot 支持使用用 HTML 发送邮件。

我们在 MailService 中添加支持 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) 来实现。

和文本邮件发送代码对比,富文本邮件发送使用 MimeMessageHelper 类,该类支持发送复杂邮件模板,支持文本、附件、HTML、图片等。

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

@Test
public void testHtmlMail() throws Exception {
    String content = 
    "<html>\n" + 
        "<body>\n" + 
            "<h3>hello world ! 这是一一封html邮件!</h3>\n" +
        "</body>\n" +
    "</html>";

    mailService.sendHtmlMail("test@126.com","这是一封HTML邮件", content);
}

代码中拼接出的 HTML 的 String 字符串交给 MimeMessageHelper 来处理理,最后由邮件客户端负责渲染显示内容。

发送带附件的邮件

在 MailService 添加 sendAttachmentsMail 方法,发送带附件的邮件主要是使用 FileSystemResource 对文件进行封装,再添加到 MimeMessageHelper 中。

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

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

在测试类中添加测试方法:

@Test
public void sendAttachmentsMail() {
    String filePath = "e:\\temp\\fastdfs-client-java-5.0.0.jar";
    mailService.sendAttachmentsMail("test@126.com", "主题:带附件的邮件", "有附件,请查收!", filePath);
}

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

发送带静态资源的邮件

邮件中的静态资源一般指图片,在 MailService 中添加 sendInlineResourceMail 方法:

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 = "e:\\temp\\weixin.jpg";
    mailService.sendInlineResourceMail("test@126.com", "主题:这是有图片的邮件", content, imgPath, rscId);
}

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1800797.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

L45---506.相对名次(java)--排序

1.题目描述 2.知识点 &#xff08;1&#xff09;String.join(" ", words) 是 Java 中的一个语法&#xff0c;用于将数组或集合中的元素连接成一个单独的字符串&#xff0c;连接时使用指定的分隔符。这里的 " " 是作为分隔符使用的一个空格字符串。 Strin…

Bond 网卡绑定技术学习

前言&#xff1a; 为了实现网卡的高可用性&#xff0c;需要学习一下 Bond技术 1. 概念 Bond&#xff08;也被称为链路聚合、端口绑定或接口绑定&#xff09;是一种网络技术&#xff0c;用于将多个物理网络接口&#xff08;如以太网接口&#xff09;组合成一个逻辑接口。这样做…

循环语句大揭秘:while、do-while、for、foreach你都掌握了吗?

哈喽&#xff0c;各位小伙伴们&#xff0c;你们好呀&#xff0c;我是喵手。运营社区&#xff1a;C站/掘金/腾讯云&#xff1b;欢迎大家常来逛逛 今天我要给大家分享一些自己日常学习到的一些知识点&#xff0c;并以文字的形式跟大家一起交流&#xff0c;互相学习&#xff0c;一…

高质量 HarmonyOS 权限管控流程

高质量 HarmonyOS 权限管控流程 在 HarmonyOS 应用开发过程中&#xff0c;往往会涉及到敏感数据和硬件资源的调动和访问&#xff0c;而这部分的调用就会涉及到管控这部分的知识和内容了。我们需要对它有所了解&#xff0c;才可以在应用开发中提高效率和避免踩坑。 权限管控了…

STM32项目分享:智能门禁锁系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 2.PCB板及元器件图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; https://www.bilibili.c…

使用 stress 命令进行Linux CPU 压力测试

大家好&#xff0c;在现代计算机系统中&#xff0c;对系统性能和稳定性的评估是至关重要的。特别是在服务器环境中&#xff0c;我们需要确保系统能够在高负载情况下稳定运行&#xff0c;以满足用户的需求。而 CPU 是系统中最关键的组件之一&#xff0c;其性能直接影响着整个系统…

探索加密货币:打造Web3项目与企业的新篇章

本文来源香港Web3媒体&#xff1a;Techub News 在数字化浪潮席卷全球的今天&#xff0c;加密货币及Web3项目和企业正成为引领创新的重要力量。作为这一领域的观察者&#xff0c;Mark Beylin深入剖析了如何通过打造人们真正需要的代币&#xff0c;来推动Web3项目的成功与企业的蓬…

电脑开机出现英文字母,如何解决这个常见问题?

电脑开机时出现英文字母的情况通常意味着系统在启动过程中遇到了问题。这些英文字母可能是错误信息、系统提示或BIOS设置问题。通过理解这些信息并采取适当的措施&#xff0c;您可以解决大多数启动问题。本文将介绍三种解决电脑开机出现英文字母问题的方法&#xff0c;帮助您恢…

VSCode搭建开发环境--从PyCharm到拥抱vscode

VSCode搭建开发环境 前言安装扩展全局配置文件单个项目的配置快捷键 前言 最近自己的PyCharm Professional的License过期了&#xff0c;导致没有一个好的开发IDE&#xff0c;于是开始拥抱免费的Visual Studio Code啦。 当然&#xff0c;不可否认的是PyCharm对于开发Python来说…

学习笔记——路由网络基础——路由概述

一、路由概述 1、路由定义与作用 路由(routing)是指导报文转发路径信息&#xff0c;通过路由可以确认转发IP报文的路径。 路由&#xff1a;是指路由器从一个接口上收到数据包&#xff0c;根据数据包的目的地址进行定向并转发到另一个接口的过程。 路由(routing)的定义是指分…

超详解——Python模块文档——小白篇

目录 1. Unix起始行 示例&#xff1a; 2. 对象和类型 示例&#xff1a; 3. 一切都是对象 示例&#xff1a; 4. 理解对象和引用 示例&#xff1a; 5. 理解对象和类型 示例&#xff1a; 6. 标准类型 示例&#xff1a; 7. 其他内建类型 示例&#xff1a; 8. 类型的类…

本地运行ChatTTS

TTS 是将文字转为语音的模型&#xff0c;最近很火的开源 TTS 项目&#xff0c;本地可以运行&#xff0c;运行环境 M2 Max&#xff0c;差不多每秒钟 4&#xff5e;&#xff5e;5 个字。本文将介绍如何在本地运行 ChatTTS。 下载源码 首先下载源代码 git clone https://github…

【Mac】Media Encoder 2022 for Mac(媒体编码器)V22.6.1软件介绍

软件介绍 Media Encoder 2022 for Mac是一款有着十分丰富硬件设备的编码格式设置和专门设计的预设设置功能的媒体编码器软件&#xff0c;Media Encoder Mac版能够帮助用户导出与特定交付媒体兼容的文件&#xff0c;可以很容易地将项目导出到任何屏幕上的可播放内容中。软件同时…

PVE管理虚拟机节点

今天使用PVE命令安装虚拟机。 ‍ 查看所有虚拟机 qm list 查看所有虚拟机 ​​ 创建虚拟机 qm create 创建虚拟机 qm create 106 --name vm-test --memory 2048 --net0 virtio,bridgevmbr0基础配置 这条命令会创建一个 VM&#xff0c;ID 为 106​&#xff0c;名称为 myvm​…

数据挖掘--挖掘频繁模式、关联和相关性:基本概念和方法

频繁项集、闭项集和关联规则 频繁项集&#xff1a;出现的次数超过最小支持度计数阈值 闭频繁项集&#xff1a;一个集合他的超集(包含这个集合的集合)在数据库里面的数量和这个集合在这个数据库里面的数量不一样,这个集合就是闭项集 如果这个集合还是频繁的,那么他就是极大频…

Leetcode3171. 找到按位与最接近 K 的子数组

Every day a Leetcode 题目来源&#xff1a;3171. 找到按位与最接近 K 的子数组 解法1&#xff1a;位运算 优化&#xff1a; 代码&#xff1a; /** lc appleetcode.cn id3171 langcpp** [3171] 找到按位与最接近 K 的子数组*/// lc codestart class Solution { public:int m…

【应用浅谈】Odoo的库存计价与产品成本(三)

序言:时间是我们最宝贵的财富,珍惜手上的每个时分 Odoo的库存&#xff08;Stock&#xff09;模块拥有众多功能&#xff0c;其中库存计价是一项非常重要的功能&#xff0c;原生的成本方法分三种&#xff1a;【标准成本】&#xff0c;【平均成本】&#xff0c;【先进先出】&#…

Fastgpt接入Whisper本地模型实现语音输入

前言 FastGPT 默认使用了 OpenAI 的 LLM 模型和语音识别模型,如果想要私有化部署的话,可以使用openai 开源模型Whisper。参考文章 《openai 开源模型Whisper语音转文本模型下载使用》 开源项目地址 : 兼容openai接口api服务 https://gitee.com/taisan/whisper-api 设置安…

一次改SQLMAP的操作

前言 sqlmap这个工具&#xff0c;相信各位大佬们都不陌生&#xff0c;但sqlmap虽好&#xff0c;也时常会有些实际存在但无法注入的地方&#xff0c;这时候就需要我们改它的配置了&#xff0c;今天就以本人遇到的事件进行阐述。 正文 确认注入点 通过一系列测试最终确定这里…

【Java笔记】第10章:接口

前言1. 接口的概念与定义2. 接口的声明与语法3. 接口的实现4. 接口的继承5. 接口的默认方法6. 接口的静态方法7. 接口的私有方法8. 接口的作用9. 接口与抽象类的区别10. 接口在Java集合中的应用结语 上期回顾:【Java笔记】第9章&#xff1a;三个修饰符 个人主页&#xff1a;C_G…