Java实现邮箱验证码

news2024/12/24 21:42:25

目录:

前言

一、POM依赖

二、获取验证码

三、配置文件

四、业务代码

        1.service接口

        2.service实现类

        3.相关工具类Util

        4.查询Redis数据库

        5.接收邮件 


前言

邮箱验证码是一个常见的功能,常用于邮箱绑定、修改密码等操作上,本篇博客只要讲的是如何使用springboot实现验证码的发送功能。我使用redis数据库保存临时的邮箱验证码信息。


一、POM依赖

    <dependencies>        
        <!--mail邮件发送-->
        <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>
        <!-- redis 连接池 -->
        <!--新版本连接池lettuce-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>
    </dependencies>

二、获取验证码

步骤:1.登录QQ邮箱-->2.设置-->3.账户安全-->4.开启服务(POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务)

按要求发送短信,即可获取授权码(获取的授权码记得保存,之后会用到哦) 

三、配置文件

  • username:是你的邮箱,不是用户名
  • password:是授权码,不是密码
  • host:是SMTP服务器,不是IP地址
spring:
  # mail邮箱
  mail:
    # SMTP服务器(我用的是QQ邮箱的SMTP服务器地址,如果用的其它邮箱请另行百度搜索)
    host: smtp.qq.com
    # 发送验证码的邮箱(发件人的邮箱)
    username: ***@qq.com
    # 授权码
    password: ***
    # 编码
    default-encoding: utf-8
    # 其它参数
    properties:
      mail:
        smtp:
          # 如果是用SSL方式,需要配置如下属性,使用qq邮箱的话需要开启
          ssl:
            enable: true
            required: true
          # 邮件接收时间的限制,单位毫秒
          timeout: 10000
          # 连接时间的限制,单位毫秒
          connection-timeout: 10000
          # 邮件发送时间的限制,单位毫秒
          write-timeout: 10000




PS:我这里用的是QQ邮箱做的演示,如果用的其它邮箱请另行百度搜索,替换SMTP地址。

四、业务代码

1.service接口
// 发送邮件
String sendEmail(String email);
2.service实现类

PS:需要先判断这个邮箱是否在redis中已经存在key,防止重复发送。

import com.test.java.util.VerifyCodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeUtility;
import java.util.concurrent.TimeUnit;

/**
 * 用户业务实现类
 */
@Service
@Slf4j
public class UserServiceImpl implements UserService {

    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private JavaMailSender javaMailSender;
    @Resource
    private VerifyCodeUtil verifyCodeUtil;


    @Override
    public String sendEmail(String email) {
        if (StringUtils.isBlank(email)) {
            throw new RuntimeException("未填写收件人邮箱");
        }
        // 定义Redis的key
        String key = "msg_" + email;

        ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
        String verifyCode = valueOperations.get(key);
        if (verifyCode == null) {
            // 随机生成一个6位数字型的字符串
            String code = verifyCodeUtil.generateVerifyCode(6);
            // 邮件对象(邮件模板,根据自身业务修改)
            SimpleMailMessage message = new SimpleMailMessage();
            message.setSubject("**游戏注册邮箱验证码");
            message.setText("尊敬的用户您好!\n\n感谢您注册**游戏。\n\n尊敬的: " + email + "您的校验验证码为: " + code + ",有效期5分钟,请不要把验证码信息泄露给其他人,如非本人请勿操作");
            message.setTo(email);

            try {
                // 对方看到的发送人(发件人的邮箱,根据实际业务进行修改,一般填写的是企业邮箱)
                message.setFrom(new InternetAddress(MimeUtility.encodeText("**游戏官方") + "<1*********@qq.com>").toString());
                // 发送邮件
                javaMailSender.send(message);
                // 将生成的验证码存入Redis数据库中,并设置过期时间
                valueOperations.set(key, code, 5L, TimeUnit.MINUTES);
                log.info("邮件发送成功");
                return "邮件发送成功";
            } catch (Exception e) {
                log.error("邮件发送出现异常");
                log.error("异常信息为" + e.getMessage());
                log.error("异常堆栈信息为-->");
                return "邮件发送失败";
                //e.printStackTrace();
                //throw new RuntimeException(e);
            }
        } else {
            return "验证码已发送至您的邮箱,请注意查收";
        }
    }


3.相关工具类Util
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.Random;

/**
 * 验证码相关工具类
 */
@Component
public class VerifyCodeUtil {

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 随机生成指定长度字符串验证码
     *
     * @param length 验证码长度
     */
    public String generateVerifyCode(int length) {
        String strRange = "1234567890";
        StringBuilder strBuilder = new StringBuilder();

        for (int i = 0; i < length; ++i) {
            char ch = strRange.charAt((new Random()).nextInt(strRange.length()));
            strBuilder.append(ch);
        }
        return strBuilder.toString();
    }

    /**
     * 校验验证码(可用作帐号登录、注册、修改信息等业务)
     * 思路:先检查redis中是否有key位对应email的键值对,没有代表验证码过期;如果有就判断用户输入的验证码与value是否相同,进而判断验证码是否正确。
     */
    public Integer checkVerifyCode(String email, String code) {
        int result = 1;
        ValueOperations<String, String> valueOperations = stringRedisTemplate.opsForValue();
        String msgKey = "msg_" + email;
        String verifyCode = valueOperations.get(msgKey);
        /*校验验证码:0验证码错误、1验证码正确、2验证码过期*/
        if (verifyCode == null) {
            result = 2;
        } else if (!code.equals(verifyCode)) {
            result = 0;
        }
        // 如果验证码正确,则从redis删除
        if (result == 1) {
            stringRedisTemplate.delete(msgKey);
        }
        return result;
    }
}
4.查询Redis数据库

5.接收邮件 

如果这篇文章对您有所帮助,或者有所启发的话,求一键三连:点赞、评论、收藏➕关注,您的支持是我坚持写作最大的动力。

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

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

相关文章

vue-i18n 实现国际化,支持切换不同语言

需求&#xff1a;后台管理系统&#xff0c;可以实现语言切换 实现过程&#xff1a;用的i18n来实现的语言切换&#xff0c;网上能看到好多模板&#xff0c;根据自己的需求&#xff0c;修改一下即可使用&#xff0c;大概都是差不多的&#xff0c;因为涉及到后端&#xff0c;所以…

如何在 javascript 中交换数组元素

文章目录 在 JavaScript 中使用临时变量交换数组元素使用 ES6 析构函数赋值在 JavaScript 中交换数组元素使用按位异或和数组迭代在 JavaScript 中交换数组元素 交换两个元素的传统方法是使用临时变量。 在 JavaScript 中&#xff0c;我们可以轻松地将数组对象重新分配给默认设…

实验一(7 3)

实验分析&#xff1a; 1.使用合理IP地址规划网络&#xff0c;各自创建环回接口&#xff0c;R1-R2-R3-R4-R5 RIP 100运行版本2&#xff0c;R6-R7 RIP 200 运行版本1 方法&#xff1a;要使得两个不同rip版本互通&#xff0c;需要在r4连通r6&#xff08;或r6连通r4&#xff09;的…

android 如何分析应用的内存(十)——malloc统计和libmemunreachable

android 如何分析应用的内存&#xff08;十&#xff09; 接下来介绍native heap内存的第四个板块————malloc统计和libmemunreachable malloc统计 malloc统计是标准c库提供的接口。他有两个调用接口如下&#xff1a; #include <malloc.h>struct mallinfo mallinfo…

敏捷开发Scrum

目录 1 Scrum概览1.2 理论基础1.2.1 透明性&#xff08;Transparency&#xff09;1.2.2 检验&#xff08;Inspection&#xff09;1.2.3 适应&#xff08;Adaptation&#xff09; 2 三个角色2.1 产品负责人&#xff08;Product Owner&#xff09;2.1.1 职责2.1.2 人选 2.2 流程管…

JDK多版本管理工具jenv

JENV mac jdk版本管理工具 Mac 安装jenv可以使用brew brew install jenv配置jenv zsh配置方式&#xff1a; echo export PATH"$HOME/.jenv/bin:$PATH" >> ~/.zshrc echo eval "$(jenv init -)" >> ~/.zshrcbash配置方式&#xff1a; ech…

海上明月共潮生【InsCode Stable Diffusion 美图活动一期】

一、 Stable Diffusion 模型在线使用地址&#xff1a; https://inscode.csdn.net/inscode/Stable-Diffusion 购买 右下角点击 Stable Diffusion WebUI 进入工作界面 二、模型相关版本和参数配置&#xff1a; 模型&#xff1a;chilloutmix_NiPrunerdFp32Fix.safetensors…

解决Python的SyntaxError: Non-UTF-8 code starting with ‘\xbb‘问题

文章目录 一、报错二、分析三、解决3.1 方法一3.2 方法二3.3 方法三 一、报错 在程序中&#xff0c;line 8为含有中文的注释&#xff0c;编译后出现了SyntaxError: Non-UTF-8 code starting with \xbb的报错&#xff0c;具体如下图。 二、分析 这个错误是由于Python解释器无…

教你如何快速批量添加滚动文字水印

在视频中添加滚动的文字水印可以增加视频的专业感和吸引力&#xff0c;但手动给大量视频添加滚动文字水印是一项费时费力的任务。下面是一个快速批量给大量视频添加滚动文字水印的方法&#xff0c;有需要的小伙伴们可以进来学习一下&#xff01; 今天分享的方法会使用到一个剪辑…

IDEA 中 gradle面板显示重复工程

使用 IDEA 构建多模块工程时&#xff0c;每新建一个模块&#xff0c;gradle 构建后&#xff0c;面板上就会出现一个重复的根工程&#xff0c;如下图红框部分&#xff0c;怎么处理下

ASIC数字设计:前端设计、验证、后端实现

前端设计 数字系统设计中有三个重要的设计级别概念&#xff1a;行为级&#xff08;Behavior Level&#xff09;、寄存器传输级&#xff08;Register Transfer Level&#xff09;和门级&#xff08;Gate level&#xff09;。其中&#xff0c; 行为级通过行为级算法描述数字系统&…

zabbix 报警测试报错

一、报错描述 在测试报警媒介时&#xff0c;报错如下: main.py脚本是在windows上的pycharm上编写的&#xff0c;在windows上运行没有问题&#xff0c;放在linux服务器上使用python3 main.py 运行也没有问题&#xff0c;但是使用./main.py执行就报错 [rootp0-tkhijbs-broadco-…

十、Docker虚悬镜像

学习参考&#xff1a;尚硅谷Docker实战教程、Docker官网、其他优秀博客(参考过的在文章最后列出) 目录 前言一、介绍二、如何产生的&#xff1f;三、尝试弄一个三、查看、删除虚悬镜像3.1 查看虚悬镜像3.2 删除虚悬镜像 总结 前言 什么是虚悬镜像&#xff1f; 一、介绍 虚悬…

【LEAP模型】能源供应转换、需求及碳排放预测、平衡表核算、模型框架构建、操作、情景设计、结果分析、优化、预测结果不确定性分析等

模型简介&#xff1a; 中文名&#xff1a;LEAP模型 外文名&#xff1a;Long Range Energy Alternatives Planning System/ Low emission analysis platform LEAP模型[1]允许研究者根据研究目的、数据可获取度、研究对象特点等灵活构建模型结构&#xff0c;十分适用于能源数据…

如何修改Jupyter Notebook的默认目录和默认浏览器

一、修改默认目录 Jupyter Notebook的文件默认保存目录是C:\Users\Administrator&#xff0c;默认目录可在黑窗口中查看&#xff0c;如下图所示&#xff1a; 为了方便文档的管理&#xff0c;可将默认目录修改成自己想保存的地方。修改方法如下&#xff1a; 1、找到config文件 …

centos搭建ftp服务器window使用ftp命令

part 1、centos搭建ftp服务器 参考链接&#xff1a;Linux搭建FTP&#xff0c;并使用Windows和IE浏览器访问FTP服务_一二三&#xff0c;开花的博客-CSDN博客 part 2、window使用ftp服务器 参考链接&#xff1a;Windows命令之ftp命令「建议收藏」-腾讯云开发者社区-腾讯云 备…

深度学习准确率提升之天花板分析

案例1 OCR文字识别流水线主要分为三个模块&#xff1a;文字检测->字符分割->字符识别 训练完成后整个系统的准确率是72%&#xff0c;需要进一步提升准确率就需要单独分析每个模块的提升空间。 1&#xff09;对于文件检测模块&#xff0c;把训练集的图像人工确保标注准…

分享一份不算优秀的HTML简历模版

一份算不上优秀的HTML简历模版 Demo http://sylvanding.github.io/cv Repo https://github.com/sylvanding/cv 示例 总结了一下本科四年都做了些什么&#xff0c;把这套模版分享给大家。

【C】数据在内存中的存储

前言 > 在内存中&#xff0c;整型和浮点型存储的方式是不同的&#xff0c;从内存中读取的方式也是有所差异的&#xff0c;这篇文章主要介绍整型和浮点型在内存中存储的方式。 整型在内存中的存储 计算机中有符号数有3种表示方式&#xff1a; 原码&#xff1a;直接将二进制按…

Material —— RBD(Houdini To UE)

目录 一&#xff0c;ABC to UE 二&#xff0c;FBX to UE 三&#xff0c;APEX to UE 四&#xff0c;VAT to UE Houdini刚体碎块导入UE&#xff0c;有两个方面需还原&#xff0c;一是材质还原&#xff0c;一是动态还原&#xff1b; 一&#xff0c;ABC to UE 材质方面&#…