springboot集成邮箱验证功能
准备工作
开启SMTP服务
前往你的邮箱网站,以网易邮箱为例,打开网易邮箱地址,登录你的邮箱,进入邮箱管理后台界面。点击“设置”》》“POP3/SMTP/IMAP”后,点击开启SMTP服务即可。
技术实现
Spring Boot 发送邮件验证码的功能,主要用到了spring-boot-starter-mail工具包实现邮件的发送功能,利用junit-vintage-engine工具包实现了html邮件模板功能,利用easy-captcha工具包生成随机验证码 的功能!
引入依赖
<!--引入mail依赖--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency><!--mail模板--><dependency><groupId>org.junit.vintage</groupId><artifactId>junit-vintage-engine</artifactId><scope>test</scope><exclusions><exclusion><groupId>org.hamcrest</groupId><artifactId>hamcrest-core</artifactId></exclusion></exclusions></dependency><!--验证码--><dependency><groupId>com.github.whvcse</groupId><artifactId>easy-captcha</artifactId><version>1.6.2</version></dependency>
相关配置
然后再spring的配置文件中,设置mail相关配置:
spring:mail:host: smtp.yeah.comusername: 你的邮箱password: 邮箱授权码default-encoding: UTF-8protocol: smtpproperties:mail:smtp:auth: true # 启用SMTP认证starttls:enabled: true # 启用SMTP认证required: true # 必须采用加密链接
代码实现
创建一个MailService类,实现邮件发送的功能,代码如下:
import com.tarzan.nav.modules.admin.service.sys.SysConfigService;
import com.tarzan.nav.utils.DateUtil;
import lombok.extern.slf4j.Slf4j;
import org.antlr.stringtemplate.StringTemplate;
import org.antlr.stringtemplate.StringTemplateGroup;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;import javax.annotation.Resource;
import javax.mail.MessagingException;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import java.io.UnsupportedEncodingException;
import java.util.Objects;/*** @author lsyong*/
@Component("mailService")
@Slf4j
public class MailService {private static final StringTemplateGroup templateGroup;@Resourceprivate SysConfigService sysConfigService;static{String classpath = Objects.requireNonNull(MailService.class.getClassLoader().getResource("")).getPath();templateGroup = new StringTemplateGroup("mailTemplates", classpath + "/mailTemplates");}public static String IMG_BASE_URL;public static String ACTIVATE_CONTEXT="http:";public static String RESET_PWD_CONTEXT;@Value("${spring.mail.username}")private String username;@Resourceprivate JavaMailSender mailSender;private void sendMail(String to, String subject, String body) {MimeMessage mail = mailSender.createMimeMessage(); try {MimeMessageHelper helper = new MimeMessageHelper(mail, true, "utf-8");helper.setFrom(new InternetAddress(MimeUtility.encodeText(sysConfigService.getSiteName())+"<"+username+">").toString());helper.setTo(to);helper.setSubject(subject);helper.setText(body, true);helper.setSentDate(DateUtil.now());mailSender.send(mail);} catch (MessagingException|UnsupportedEncodingException e) {log.error(e.getMessage());}}/*** send activation mail to* @param to,key*/public void sendAccountActivationEmail(String to, String key){StringTemplate activation_temp = templateGroup.getInstanceOf("activation");activation_temp.setAttribute("img_base_url", IMG_BASE_URL);activation_temp.setAttribute("email", to);activation_temp.setAttribute("href", ACTIVATE_CONTEXT+key+"?email="+to);activation_temp.setAttribute("link", ACTIVATE_CONTEXT+key+"?email="+to);sendMail(to, sysConfigService.getSiteName()+"账户激活", activation_temp.toString());}@Asyncpublic void sendEmailCode(String to, String code){StringTemplate activation_temp = templateGroup.getInstanceOf("verificationCode");activation_temp.setAttribute("img_base_url", IMG_BASE_URL);activation_temp.setAttribute("email", to);activation_temp.setAttribute("code", code);sendMail(to, sysConfigService.getSiteName()+"邮箱验证码", activation_temp.toString());}/*** send change password link to* @param to,key*/public void sendResetPwdEmail(String to, String key){StringTemplate activation_temp = templateGroup.getInstanceOf("resetpwd");activation_temp.setAttribute("img_base_url", IMG_BASE_URL);activation_temp.setAttribute("href", RESET_PWD_CONTEXT+"?key="+key+"&email="+to);activation_temp.setAttribute("link", RESET_PWD_CONTEXT+"?key="+key+"&email="+to);sendMail(to, sysConfigService.getSiteName()+"账户密码重置", activation_temp.toString());}
}
相关文章:

springboot集成邮箱验证功能
准备工作 开启SMTP服务 前往你的邮箱网站,以网易邮箱为例,打开网易邮箱地址,登录你的邮箱,进入邮箱管理后台界面。点击“设置”》》“POP3/SMTP/IMAP”后,点击开启SMTP服务即可。 技术实现 Spring Boot 发送邮件验证…...

HarmonyOS应用程序框架——UIAbility实操
UIAbility概述 UIAbility是一种包含用户界面的应用组件,主要用于和用户进行交互。UIAbility也是系统调度的单元,为应用提供窗口在其中绘制界面。 每一个UIAbility实例,都对应于一个最近任务列表中的任务。 一个应用可以有一个UIAbility&…...

数实融合!低代码推动工业数字化转型走“深”向“实”
当下,“数字化、智能化”已经不再是新鲜词。毕竟,在早几年前就已经有企业喊出大举进军数字化的口号,轰轰烈烈的数字化转型运动也持续了很长一段时间,有一些业内人士甚至判断“如今的企业数字化已经走过了成熟期,来到了…...
OpenGL学习资料
1.学习网站 Song Ho Ahn LearnOpenGL GAMES101:现代计算机图形学入门 OpenGL 官网 2.书籍 Fundamentals of computer graphics OpenGL ES 3.0编程指南 计算机图形学(OpenGL版)第3版 3.参考的一些文章 颜色缓冲区 深度缓冲 VBO,VAO和EBO详解 深入探索透视投影变…...

字符串指令集
字符串指令的格式 例子1就成功发送了指令 例子2就是发送的字符串有误 查询当前位置就会在附加信息中返回当前座位的坐标 第一个指令的参数就是闪灯的两个参数 如第一个示例就是10ms On Time 第二个就是Off Time 使用标准库来接收字符串命令 字符串指令的接收 因为一个指令就是…...

行云海CMS SQL注入漏洞复现
0x01 产品简介 行云海cms是完全开源的一套CMS内容管理系统,简洁,易用,安全,稳定,免费。 0x02 漏洞概述 行云海cms中ThinkPHP在处理order by排序时可利用key构造SQL语句进行注入,LtController.class.php中发现传入了orderby未进行过滤导致sql注入。攻击者除了可以利用 SQL 注入…...

窗口函数之 first_value() 和 last_value()
这次,我要从**last_value()**开始写! last_value() 众所周知,first_value() 和 last_value() 的作用是返回窗口中某个字段的第一行的值和最后一行的值。 但是在应用的时候,突然发现使用last_value() 返回了不止一条数据&#x…...
习题练习讲解
前言:这又是一个新坑,算上之前的4个坑这是第五个坑(1、C/C的讲解,2、C语言小游戏,3、大学生活,4、假哲家因为某些原因没GS),这个就是发一些自己在刷题的过程中遇到自己感觉还不错的习…...

C++STL的string模拟实现
文章目录 前言string的成员变量成员函数构造函数拷贝构造赋值重载 模拟实现string各种接口print迭代器普通迭代器const迭代器 string比较大小push_backinsert 和 eraseinserterase reserve和resizereserveresize swapfindcout和cincoutcin 前言 今天要讲string的底层实现&…...

基于ZLMediaKit的webrtc实时视频传输demo搭建
环境 ubuntu 20.04 gcc version 9.4.0 cmake version 3.16.3 部署ZLMediaKit流媒体服务器 安装openssl 首先可以检查一下自己的openssl的版本如果是1.1.1以上就可以忽略这一步 wget https://www.openssl.org/source/openssl-1.1.1k.tar.gz tar -xvzf openssl-1.1.1k…...
LeetCode双指针:有序数组中的单一元素
LeetCode双指针:有序数组中的单一元素 题目描述 给你一个仅由整数组成的有序数组,其中每个元素都会出现两次,唯有一个数只会出现一次。 请你找出并返回只出现一次的那个数。 你设计的解决方案必须满足 O(log n) 时间复杂度和 O(1) 空间复…...

熬夜会秃头——Beta冲刺总结随笔
这个作业属于哪个课程2301-计算机学院-软件工程社区-CSDN社区云这个作业要求在哪里团队作业—beta冲刺事后诸葛亮-CSDN社区这个作业的目标总结Beta冲刺团队名称熬夜会秃头团队置顶集合随笔链接熬夜会秃头——Beta冲刺置顶随笔-CSDN社区 目录 一、Beta冲刺开始前设立的任务完成…...
C++函数模板案例
利用函数模板封装一个排序的函数,可以对不同数据类型数组进行排序排序规则从大到小,排序算法为选择排序分别利用char数组和int数组进行测试 #include<iostream> using namespace std;template<class T> void myswap(T& a, T& b) {T…...

同旺科技 USB TO RS-485 定制款适配器--- 拆解(三)
内附链接 1、USB TO RS-485 定制款适配器 ● 支持USB 2.0/3.0接口,并兼容USB 1.1接口; ● 支持USB总线供电; ● 支持Windows系统驱动,包含WIN10 / WIN11系统32 / 64位; ● 支持Windows RT、Linux、Mac OS X、Windo…...
Vue学习计划-Vue2--Vue核心(六)过滤器和自定义指令
1. 过滤器 定义:对要显示的数据进行特定格式转换再显示(适用于一些简单逻辑的处理)语法: 注册过滤器:Vue.filter(name, callback) 或 new Vue{filters:{}}使用过滤器:{{ xx | 过滤器名 }} 或 v-bind:属性 …...
Codeforces Round 913 (Div. 3) (A-G)
后天就是 I C P C ICPC ICPC杭州站了,今天把之前做的 d i v 3 div3 div3题补一下,打完这场杭州站这赛季除了 E C F i n a l EC\,\,Final ECFinal就结束了,以后应该要多打 c f cf cf比赛练习保持手感,争取下赛季冲一下金牌。 感觉这…...

CSS——sticky定位
1. 大白话解释sticky定位 粘性定位通俗来说,它就是相对定位relative和固定定位fixed的结合体,它的触发过程分为三个阶段 在最近可滚动容器没有触发滑动之前,sticky盒子的表现为相对定位relative【第一阶段】, 但当最近可滚动容…...

Redis hash表源码解析
1、 整体数据结构 链式hash解决hash冲突、采用渐进式hash来完成扩容过程。 /** 哈希表节点*/ typedef struct dictEntry {// 键void *key;// 值union {void *val;uint64_t u64;int64_t s64;} v;// 指向下个哈希表节点,形成链表struct dictEntry *next;} dictEntry;…...

dll动态链接库【C#】
1说明: 在C#中,dll是添加 【类库】生成的。 2添加C#的dll: (1)在VS中新建一个Windows应用程序项目,并命名为TransferDll。 (2)打开Windows窗体设计器,从工具箱中为窗体…...
Linux 系统设置cpu频率
source_code: https://github.com/emagii/cpufrequtils cpufreq-set - A small tool which allows to modify cpufreq settings.(修改内存频率的工具) cpufreq-set allows you to modify cpufreq settings without having to type e.g. “/sys/devices…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...

【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
在HarmonyOS ArkTS ArkUI-X 5.0及以上版本中,手势开发全攻略:
在 HarmonyOS 应用开发中,手势交互是连接用户与设备的核心纽带。ArkTS 框架提供了丰富的手势处理能力,既支持点击、长按、拖拽等基础单一手势的精细控制,也能通过多种绑定策略解决父子组件的手势竞争问题。本文将结合官方开发文档,…...

基于Flask实现的医疗保险欺诈识别监测模型
基于Flask实现的医疗保险欺诈识别监测模型 项目截图 项目简介 社会医疗保险是国家通过立法形式强制实施,由雇主和个人按一定比例缴纳保险费,建立社会医疗保险基金,支付雇员医疗费用的一种医疗保险制度, 它是促进社会文明和进步的…...
Objective-C常用命名规范总结
【OC】常用命名规范总结 文章目录 【OC】常用命名规范总结1.类名(Class Name)2.协议名(Protocol Name)3.方法名(Method Name)4.属性名(Property Name)5.局部变量/实例变量(Local / Instance Variables&…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...

【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
AspectJ 在 Android 中的完整使用指南
一、环境配置(Gradle 7.0 适配) 1. 项目级 build.gradle // 注意:沪江插件已停更,推荐官方兼容方案 buildscript {dependencies {classpath org.aspectj:aspectjtools:1.9.9.1 // AspectJ 工具} } 2. 模块级 build.gradle plu…...