Spring Boot接入邮箱,完成邮箱验证码

news/2025/9/26 17:53:52/文章来源:https://www.cnblogs.com/huaguoniang/p/19113882

先知

邮箱的一些基本概念:

发送邮件
  1. STMP协议:

    1. Simple Mail Transfer Protocol ,简单邮箱传输协议,用于发送邮件的协议。

    2. 基于TCP,保证可靠性,但不安全,是明文传输

    3. Spring Boot默认也是基于此协议进行发送邮件

接收邮件
  1. POP3协议:

    1. Post Office Protocol 3:邮局通信协议第三版,用于接收邮箱的标准协议。

    2. 一次性取信”,客户端把邮件下载到本地之后,通常会从服务器上删除(可以配置保留副本)。如果没有设置,电脑上收了邮件,手机上就没法再看到这封邮件

  2. IMAP协议:

    1. Internet Message Access Protocol : 互联网消息访问协议,是POP3的代替,也是用于接收邮件的协议

    2. 云端管理”:客户端拉去邮件,只是将“视图”同步到本地,不会删除,始终保存在服务器上。

    3. Gmail、QQ邮箱、OutLook等现代邮箱,都是用的IMAP协议

邮箱的传送流程

当你用QQ邮箱向网易邮箱发送了一封邮件,会发生什么?

  1. QQ邮箱客户端会使用SMTP协议将 邮件 发送到自家的邮件服务器上

  2. QQ邮箱服务器,接收到一封邮件,然后会解析目标地址的域名

  3. QQ邮箱服务器,识别到是其他服务器上的域名,就会进行转发,同样使用SMTP协议发送

  4. 网易邮箱服务器接收到一封邮件,发现是目标地址是自己的域名,就将信封存储在服务器上

  5. 网易邮箱客户器上线,查看服务器上有没有邮件,如果有,就拉取。使用IMAP或者POP3协议

邮箱开通第三方服务

  1. 如果你使用的是飞书邮箱

找到邮箱的位置,“第三方邮箱客户端登陆”

随便选择一个设备

生成,获取到授权码、用户名、发信服务器

  1. 如果你使用的是QQ邮箱

找到账户中心

开启POP3、IMAP等服务

选择你的验证方式,即可生成授权码

  1. 其他的网易邮箱等,获取授权码的方式类似

邮箱集成使用

说明:以下的使用,参考Spring中文网

  1. 依赖

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-mail</artifactId>
</dependency>
  1. 配置文件

spring:mail:# 指定邮箱的服务器地址host: smtp.feishu.cn# 执行邮箱的发送者,由哪一个邮箱账号来发送邮件username: huag****@ifree8.com# 邮件的授权码,邮箱账号需要开通第三方服务password: 29F7s********default-encoding: UTF-8
  1. 测试

@Test
public void test() throws Exception {// 直接创建 JavaMailSenderImpl 实现类JavaMailSenderImpl javaMailSender = new JavaMailSenderImpl();javaMailSender.setDefaultEncoding("utf-8");javaMailSender.setHost("smtp.qq.com");             javaMailSender.setPort(465);                       javaMailSender.setUsername("747692844@qq.com");    javaMailSender.setPassword("<你的密码/授权码>");     javaMailSender.setProtocol("smtps");// 创建一个邮件消息MimeMessage message = javaMailSender.createMimeMessage();// 创建 MimeMessageHelperMimeMessageHelper helper = new MimeMessageHelper(message, false);// 发件人邮箱和名称helper.setFrom("747692844@qq.com", "springdoc");// 收件人邮箱helper.setTo("admin@springboot.io");// 邮件标题helper.setSubject("Hello");// 邮件正文,第二个参数表示是否是HTML正文helper.setText("Hello <strong> World</strong>!", true);// 发送javaMailSender.send(message);
}

类之间的关系

在测试类中可以看到,主要涉及的主要类就是:

  1. JavaMailSender

  2. MimeMessage

  3. MimeMessageHelper

JavaMailSender

类的继承关系

  • 底层实现自MaiSender接口,接口中抽象定义了send(),而JavaMailSenderImpl就是实现类

  • JavaMailSender的作用就是主要用来发送邮件

  • 抽象理解:真实发送快递的“快递员”

MimeMessage

有了“快递员”,我们还需要“快递”——Message


public class MimeMessage extends Message implements MimePart {......public void setFrom(Address address) throws MessagingException {if (address == null) {this.removeHeader("From");} else {this.setAddressHeader("From", new Address[]{address});}}......
}

来看看里面都有哪些方法和属性

  1. setFrom():设置邮箱展示的信息,比如名称和邮箱等

  2. setRecipients():设置收件人的邮箱

  3. setText():邮件内容

  • 所以,Message的作用:主要是定义邮件内容、收件人的信息

MimeMessageHelper

Helper,“包装快递”的好帮手

看看Helper中提供了些什么方法?

为什么Helper中提供的主要方法跟Message中的方法差不多呢?

其实Helper就是用来帮助封装Message中的信息的

public class MimeMessageHelper {......public void setFrom(String from) throws MessagingException {Assert.notNull(from, "From address must not be null");this.setFrom(this.parseAddress(from));}public void setFrom(InternetAddress from) throws MessagingException {Assert.notNull(from, "From address must not be null");this.validateAddress(from);this.mimeMessage.setFrom(from);}......
}

public class MimeMessage extends Message implements MimePart {......public void setFrom(Address address) throws MessagingException {if (address == null) {this.removeHeader("From");} else {this.setAddressHeader("From", new Address[]{address});}}......
}
  • 可以看到,其实Helper提供的方法中,底层操作的对象,其实就是Message邮件信息

区别在于:

  1. MimeMessage底层的****API,能够做所有的事情

  2. MimeMessage适用的参数大多是已经封装好的,比如setFrom()方法中的参数是Address,这个类包装了邮件的地址等很多信息。

  3. MimeMessageHelper是提供的工具类,旨在于帮助用户更方便的设置Message的属性

  4. MimeMessageHelper在设置复杂邮件内容(HTML 模板邮件 + 附件),会帮助用户省去很多封装的步骤,底层进行处理,简化代码。比如setFrom()方法中的参数是String,数据更加的原始。

  • 所以,在面对更加复杂的场景,使用Helper能够帮助我们剩下很多力气

邮箱验证码案例

  1. 依赖

<dependencies><!-- Spring Boot --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency><!--redis--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><!-- Apache Commons Pool2 for Redis connection pooling --><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency><!--redisson工具集--><dependency><groupId>org.redisson</groupId><artifactId>redisson-spring-boot-starter</artifactId></dependency><!--hutool--><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId></dependency><!--Thymeleaf模板引擎--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-thymeleaf</artifactId></dependency><!--OGNL表达式语言--><dependency><groupId>ognl</groupId><artifactId>ognl</artifactId><version>3.3.4</version></dependency><!--lombok--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency>
</dependencies>
  1. 使用配置类config读取配置文件,方便后续的使用

spring:mail:host: smtp.feishu.cnusername: hua******@ifree8.compassword: 29******default-encoding: UTF-8mailFrom: hua******@ifree8.commailPersonal: 通用Ai智能体mailSubject: 邮箱验证码regExpr: ^(?!.*\.\.)[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}$variable: codehtmlTemplate: MailVerifyTemplate.html

  1. 生成模板

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>邮箱验证码</title>
</head>
<body style="font-family: Arial, Helvetica, sans-serif; background-color: #f6f8fa; padding: 20px;">
<div style="max-width: 600px; margin: auto; background: #ffffff; border-radius: 8px; padding: 30px; box-shadow: 0 2px 6px rgba(0,0,0,0.1);"><h2 style="text-align: center; color: #333333;">邮箱验证码</h2><p style="font-size: 16px; color: #333;">您好,</p><p style="font-size: 14px; color: #555;">您正在进行邮箱验证,本次验证码如下(5分钟内有效):</p><div style="text-align: center; margin: 30px 0;"><span style="font-size: 28px; font-weight: bold; color: #2d89ef; letter-spacing: 3px;" th:text="${code}">88888</span></div><p style="font-size: 14px; color: #555;">请在验证页面输入上方验证码完成验证。为保障账号安全,请勿将验证码告知他人。</p><hr style="margin: 30px 0; border: none; border-top: 1px solid #eee;"><p style="font-size: 12px; color: #999; text-align: center;">如果这不是您本人的操作,请忽略此邮件。</p>
</div>
</body>
</html>
  1. 生成自定义的JavaMailSender

因为邮箱验证码的场景,邮箱发送者一般是固定不变的,所以初始化为Bean,使用的时候直接注入即可。

  1. 使用

public interface AuthService {/*** 发送邮箱验证码* @param targetMail 接收方邮箱* @return 执行结果响应体*/ResponseEntity sendCode2Mail(String targetMail);/*** 验证邮箱验证码* @param mail 验证的邮箱* @param userCode  用户给的验证码* @return 执行结果响应体*/ResponseEntity verifyMailCode(String mail,String userCode);}
@Service
@Slf4j
public class AuthServiceImpl implements AuthService {//邮箱配置类@Autowiredprivate MailConfig mailConfig;   //Sender ,“快递员”@Autowired@Qualifier("defaultJavaMailSender")private JavaMailSender javaMailSender;  //Redis,操作工具类。其实就是RedisTemplate一些方法的封装而已。也可以直接使用RedisTemplate。//具体不在这里详说,网上也有很多教程(其实就是懒,求原谅)@Autowiredprivate RedisBase redisBase;  //包含一些Key prefix,expire time等@Autowiredprivate RedisConstant redisConstant;  @Overridepublic ResponseEntity<String> sendCode2Mail(String targetMail) {//1. 校验邮箱if (StrUtil.isBlank(targetMail)) {return ResponseEntity.failBusinessException(FAIL,"邮箱不能为空");}if (!ReUtil.isMatch(mailConfig.getRegExpr(), targetMail)) {return ResponseEntity.failBusinessException(FAIL,"邮箱格式不正确");}//2. 处理消息模板//读取模板TemplateEngine engine = TemplateUtil.createEngine(new TemplateConfig("templates", TemplateConfig.ResourceMode.CLASSPATH));Template template = engine.getTemplate(mailConfig.getHtmlTemplate());//生成随机数字int codeNum = NumberUtil.generateRandomNumber(200000, 999999,1)[0];String code = String.valueOf(codeNum);//渲染模板的变量String htmlContent = template.render(Map.of(mailConfig.getVariable(), code));//3. 封装邮件//创建消息MimeMessage message = javaMailSender.createMimeMessage();//创建helperMimeMessageHelper helper = null;//封装消息try {helper = new MimeMessageHelper(message,false);helper.setFrom(mailConfig.getMailFrom(),mailConfig.getMailPersonal()); //邮件展示,哪个邮箱账号,名称helper.setTo(targetMail);//邮件接收方helper.setSubject(mailConfig.getMailSubject()); //邮件主题helper.setText(htmlContent,true); //邮件内容} catch (Exception e) {log.error("happen error:", e);return ResponseEntity.failBusinessException(FAIL,"发生异常,请稍后重试!");}//4. 存储验证码到Redisboolean setnxFlag = redisBase.setnx(redisConstant.getMailVerifyCodeKeyPrefix() + targetMail, code, redisConstant.getMailVerifyCodeExpireSeconds());if (!setnxFlag) {return ResponseEntity.failBusinessException(FAIL,"redis异常");}//5. 发送邮件javaMailSender.send(message);//6. 返回结果return ResponseEntity.ok(null,"邮箱发送成功,请注意查收!");}@Overridepublic ResponseEntity verifyMailCode(String mail, String registMailCode) {//1. 使用邮箱从redis中获取验证码String key = redisConstant.getMailVerifyCodeKeyPrefix()+mail;String systemCode = (String)redisBase.get(key);//2. 校验验证码if (systemCode==null) {return ResponseEntity.failBusinessException(FAIL,"尚未存在邮箱验证码或验证码已过期,请重新发送邮箱验证码!");}if (!StrUtil.equals(registMailCode,systemCode)) {return ResponseEntity.failBusinessException(FAIL,"验证码错误!");}//3. 返回结果return ResponseEntity.ok();}
}

总结:

到这,我们已经学习了:

  1. 邮箱协议的基本知识

  2. 邮箱的发送和接收,在客户端和服务端的流程过程

  3. 还知道了如何开通邮箱的第三方客户端使用服务

  4. 还使用SpringBoot集成了邮箱,能够使用代码的形式,向邮箱发送邮件

以上内容是我个人根据网上的资料进行学习和转化,如果有错误,欢迎指出,共同进步哦~

(第一次写博客,写得很烂,哈哈哈见谅,希望你能够从垃圾中,灵活抽取出有用的东西吧)

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

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

相关文章

HyperWorks许可与网络安全

在高度信息化的今天,网络安全已成为企业运营中不可忽视的一环。尤其对于依赖先进工程仿真软件如HyperWorks的企业来说,保障许可与网络安全不仅关系到工作效率,更是企业核心数据安全的保障。HyperWorks致力于为用户提…

高通QCS8550开发板 + DeepSeek-R1:打造智能化商场导购实践

(原创作者@CSDN_伊利丹~怒风) 前言 在科技飞速发展的当下,智慧零售正以前所未有的态势重塑着商场的运营模式与顾客体验。商场智能导购作为智慧零售的关键一环,其精准度与高效性直接影响着消费者的购物决策和商场的…

如何提高网站转化率自己设计logo用什么软件

在当今全球化的商业版图中&#xff0c;企业为了拓展国际市场和增强竞争力&#xff0c;跨境传输数据已成为一项不可或缺的业务活动。合格的数据跨境传输方案&#xff0c;应考虑以下要素&#xff1a; 法律合规性&#xff1a;确保方案符合所有相关国家的数据保护法律和国际法规&am…

研发项目管理系统哪个好?十款热门工具全面测评

研发项目管理是一项复杂的系统工程。随着企业规模和业务复杂度的提升,仅仅依靠 Excel 或微信群来跟踪任务,已经无法满足快速迭代、跨部门协作和合规管理的需求。一款合适的 研发项目管理系统,不仅能帮助企业提高研发…

L4 vs L7 负载均衡:彻底理解、对比与实战指南 - 实践

L4 vs L7 负载均衡:彻底理解、对比与实战指南 - 实践2025-09-26 17:46 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; di…

《对软件工程的初步理解》

软件工程是一门研究如何系统化、规范化和工程化地开发与维护软件的学科。它不仅关注代码的实现,更强调需求分析、设计、测试、维护等全过程的管理与优化。通过学习软件工程,我认识到工程化方法能够提升团队协作效率和…

【IEEE出版 | 南工大主办 | 稳定EI检索】第二届自动化、电气控制系统与设备国际学术会议(AECSE 2025)

【IEEE出版 | 南工大主办 | 往届会后4个月EI检索】 第二届自动化、电气控制系统与设备国际学术会议(AECSE 2025) 2025 2nd International Conference on Automation, Electrical Control Systems and Equipment 在这…

B3863 [GESP202309 一级] 买文具

B3863 [GESP202309 一级] 买文具 解题思路 题目分析 这是一个简单的购物计算问题,需要判断小明的钱是否足够购买所需文具,并计算余额或缺额。重要知识点 1. 基本输入输出 #include <iostream>:输入输出流头文…

做哪个视频网站赚钱的哪个网站有摄影作品

一边学习,一边总结,一边分享! 写在前面 我在2023年12月组了一台“洋垃圾”的主机,一边当做台式机使用,一边当做服务器使用。这个方案算是相对比较划算的方案。我开始是打算直接单做服务器使用的,以及内存配的很高,但是后面和同事一起商量后,还是接受了后面的方案。大…

做木业网站怎样起名园区门户网站建设

MyBatis中在查询进行select映射的时候&#xff0c;返回类型可以用resultType&#xff0c;也可以用resultMap&#xff0c;resultType是直接 表示返回类型的&#xff0c;而resultMap则是对外部ResultMap的引用&#xff0c;但是resultType跟resultMap不能同时存在。 1.resultType …

Matlab通过GUI建立点云的最远点下采样(Farthest point sampling)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

B2009 计算 (a+b)/c 的值

B2009 计算 (a+b)/c 的值 解题思路 题目分析 这是一个基础的算术运算题目,要求计算三个整数的表达式 (a+b)/c 的值,其中除法是整除运算。重要知识点 1. C++基本程序结构 #include<bits/stdc++.h>:万能头文件,…

你好 博客园!

萌新驾到!!!

网站建设企业有哪些怎么用linux做网站服务器

学习自我评价4篇发布时间&#xff1a;2019-04-08在这次研究性学习中&#xff0c;我们小组在老师的指导下&#xff0c;通过全体成员的协作分工、研究探讨&#xff0c;集全体之智慧&#xff0c;个人之所学&#xff0c;充分将课本中的理论知识与生活实践相结合&#xff0c;用理论指…

成都营销网站网站设计在线crm系统

jenkins安装 下载jenkins 官网&#xff1a;Jenkins download and deployment 官方文档说明&#xff1a;Jenkins User Documentation 安装jenkins1.点击下载好的安装包&#xff0c;点击Next 2.选择一个安装路径 如果系统是windows家庭版打不开策略就创建一个txt文件&#xff0c…

网站动态程序网站建设需要条件

在当今数字化时代&#xff0c;企业对IT运维的需求日益增长&#xff0c;尤其是对于用户权限和设备管理的精细化控制。为了满足这些需求&#xff0c;监控易运维系统最近进行了一次重大的升级&#xff0c;特别是在用户权限管理和运维可视化方面取得了显著的进步。 在用户权限管理方…

设计一个网站页面需要多少钱优建网站

Imperva是网络安全解决方案的专业提供商&#xff0c;能够在云端和本地对业务关键数据和应用程序提供保护。公司成立于 2002 年&#xff0c;拥有稳定的发展和成功历史并于 2014 年实现产值1.64亿美元&#xff0c;公司的3700多位客户及300个合作伙伴分布于全球各地的90多个国家。…

东营市做网站好网站具备条件

【Python】成功解决IndexError: list index out of range &#x1f308; 个人主页&#xff1a;高斯小哥 &#x1f525; 高质量专栏&#xff1a;Matplotlib之旅&#xff1a;零基础精通数据可视化、Python基础【高质量合集】、PyTorch零基础入门教程&#x1f448; 希望得到您的订…

详细介绍:【杂谈】Godot 4.5下载指南

详细介绍:【杂谈】Godot 4.5下载指南2025-09-26 17:33 tlnshuju 阅读(0) 评论(0) 收藏 举报pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !i…

腾讯建设网站视频视频视频拍摄制作

演示视频&#xff1a; Springbootvue的导师双选管理系统&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目。 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的导师双选管理系统&#xff0c;采用M&#xff08;model&a…