小工具知识网

当前位置: 首页 > 行业知识 > SpringBoot 轻松实现发送邮箱验证码+Redis缓存(附带HTML模板)

行业知识

SpringBoot 轻松实现发送邮箱验证码+Redis缓存(附带HTML模板)

2026-11-03 12:27:26 来源:互联网转载

文章目录

    • 前言
    • 准备工作
    • 代码实现
      • 引入依赖
      • 配置文件
      • 编写相关工具类
      • 实现验证码发送代码
      • 测试

        前言

        在日常生活中,通过发送邮箱验证码来实现用户注册、密码重置和账户验证等功能在许多现代应用程序中非常常见,这里采用hutool工具包封装的一些类实现发送邮箱验证码的功能。

        准备工作

        开启POP3/SMTP服务并获取授权码,具体操作很简单,这里就不演示了

        网址:账号与安全 (qq.com)

        代码实现

        引入依赖

                                    cn.hutool            hutool-all            5.8.11                                    org.springframework.boot            spring-boot-starter-thymeleaf            3.2.0                                    com.sun.mail            javax.mail            1.6.2                                    org.springframework.boot            spring-boot-starter-data-redis        

        配置文件

        为了便于修改配置信息,因此要将邮件的相关配置写到配置文件application.yaml中

        1. 编写配置类
         @Component @ConfigurationProperties(prefix = "captcha.email") @Data public class EmailProperties {     /**      * 邮箱地址(注意:如果使用foxmail邮箱,此处user为qq号)      */     private String user;     /**      * 发件人昵称(必须正确,否则发送失败)      */     private String from;     /**      * 邮件服务器的SMTP地址      */     private String host;      /**      * 邮件服务器的SMTP端口      */     private Integer port;      /**      * 密码(授权码)      */     private String password;      /**      * 验证码过期时间      */     private Integer expireTime; }
        1. 编写相关配置信息到application.yaml文件
         captcha:   email:     from: 詩筠     password: dkhfsiudhfsd # 这里我随便填的     host: smtp.qq.com     port: 465     user: XXXXX@qq.com     expire-time: 300 # 300秒

        编写相关工具类

        验证码工具类VerifyCodeUtil:

        /** * 验证码工具类 * @author shijun * @date 2024/05/10 */public class VerifyCodeUtil {    //邮箱正则表达式    private static final Pattern EMAIL_PATTERN = Pattern.compile("^\\w+((-\\w+)|(\\.\\w+))*\\@[A-Za-z0-9]+((\\.|-)[A-Za-z0-9]+)*\\.[A-Za-z0-9]+$");    //验证码的字符集    private static final String CODES = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";    //验证码的长度,可以根据需求进行修改    private static final int CODE_LENGTH = 6;    /**     * 生成验证码     *     * @return {@link String }     */    public static String generateVerifyCode() {        Random random = new Random();        StringBuilder verifyCode = new StringBuilder(CODE_LENGTH);        for (int i = 0; i  

        Redis工具类RedisUtils:

        @Component@AllArgsConstructorpublic class RedisUtils {    private RedisTemplate redisTemplate;    /**     * 普通获取键对应值     *     * @param key 键     * @return 值     */    public Object get(String key) {        return key == null ? null : redisTemplate.opsForValue().get(key);    }    /**     * 普通设置键值     *     * @param key   键     * @param value 值     * @return true成功 false失败     */    public boolean set(String key, Object value) {        try {            redisTemplate.opsForValue().set(key, value);            return true;        } catch (Exception e) {            return false;        }    }    /**     * 普通设置键值并设置过期时间     *     * @param key   键     * @param value 值     * @param time  时间(秒) time要大于0 如果time小于等于0 将设置无限期     * @return true成功 false 失败     */    public boolean set(String key, Object value, long time) {        try {            if (time > 0) {                redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);            } else {                set(key, value);            }            return true;        } catch (Exception e) {            return false;        }    }    /**     * 删除缓存     *     * @param key 键     * @return 是否成功     */    public boolean del(String key) {        return redisTemplate.delete(key);    }    /**     * 指定缓存的失效时间     *     * @param key  键值      * @param time 时间(秒)      */    public boolean expire(String key, long time) {        try {            if (time > 0) {                redisTemplate.expire(key, time, TimeUnit.SECONDS);            }        } catch (Exception e) {            e.printStackTrace();            return false;        }        return true;    }}

        实现验证码发送代码

        1. 设计邮箱验证码模板

          为了改善用户体验,因此要设计一个好看的验证码界面

        编写EmailVerificationCode.html文件,放到src/main/resources/templates目录下:

                邮箱验证码            table {            width: 700px;            margin: 0 auto;        }        #top {            width: 700px;            border-bottom: 1px solid #ccc;            margin: 0 auto 30px;        }        #top table {            font: 12px Tahoma, Arial, 宋体;            height: 40px;        }        #content {            width: 680px;            padding: 0 10px;            margin: 0 auto;        }        #content_top {            line-height: 1.5;            font-size: 14px;            margin-bottom: 25px;            color: #4d4d4d;        }        #content_top strong {            display: block;            margin-bottom: 15px;        }        #content_top strong span {            color: #f60;            font-size: 16px;        }        #verificationCode {            color: #f60;            font-size: 24px;        }        #content_bottom {            margin-bottom: 30px;        }        #content_bottom small {            display: block;            margin-bottom: 20px;            font-size: 12px;            color: #747474;        }        #bottom {            width: 700px;            margin: 0 auto;        }        #bottom p {            padding: 10px 10px 0;            border-top: 1px solid #ccc;            color: #747474;            margin-bottom: 20px;            line-height: 1.3em;            font-size: 12px;        }        #content_top strong span {            font-size: 18px;            color: #FE4F70;        }        #sign {            text-align: right;            font-size: 18px;            color: #000000;            font-weight: bold;        }        #verificationCode {            height: 100px;            width: 680px;            text-align: center;            margin: 30px 0;        }        #verificationCode p {            height: 100px;            width: 680px;        }        .button {            color: #FE4F70;            margin-left: 10px;            height: 80px;            width: 80px;            resize: none;            font-size: 42px;            border: none;            outline: none;            padding: 10px 15px;            background: #ededed;            text-align: center;            border-radius: 17px;            box-shadow: 6px 6px 12px #cccccc,            -6px -6px 12px #ffffff;        }        .button:hover {            box-shadow: inset 6px 6px 4px #d1d1d1,            inset -6px -6px 4px #ffffff;        }    
        尊敬的用户,您好! 您正在进行注册账号操作,请在验证码中输入以下验证码完成操作: [[${a}]] 注意:此操作可能会修改您的密码、登录邮箱或绑定手机。如非本人操作,请及时登录并修改密码以保证帐户安全
        (工作人员不会向你索取此验证码,请勿泄漏!)

        此为系统邮件,请勿回复
        请保管好您的邮箱,避免账号被他人盗用

        ——詩筠

        1. 编写Controller层代码
         /**  * 验证码接口  *  * @author shijun  * @date 2024/05/10  */ @RestController @Tag(name = "验证码接口") @RequestMapping("/captcha") @RequiredArgsConstructor public class CaptchaController {      private final CaptchaService captchaService;     private final TemplateEngine templateEngine;      @Operation(summary = "发送邮箱验证码")     @Parameter(name = "email",description = "要发送的邮箱")     @GetMapping("/email-captcha")     public Result sendEmailCaptcha(String email) {         captchaService.sendEmailCaptcha(email);         return Result.success("发送成功");     }  }
        1. 编写Service层代码
         public interface CaptchaService {     /**      * 发送验证码      * @param email 邮箱      */     void sendEmailCaptcha(String email); } 
        1. 编写Service实现类

          这里涉及的BusinessException类是一个自定义异常类,用来进行业务异常处理。

          可以参考这篇文章进行学习:Spring Boot3自定义异常及全局异常捕获_springboot是如何自定义异常并捕获的-CSDN博客

         @Service @RequiredArgsConstructor public class CaptchaServiceImpl implements CaptchaService {      public static final String CAPTCHA_CODE = "captcha-email-";     private final EmailProperties emailProperties;     private final RedisUtils redisUtils;     private final TemplateEngine templateEngine;      /**      * 发送邮件验证码      * @param email 邮箱      */     @Override     public void sendEmailCaptcha(String email) {         // 验证邮件配置是否完整         validateEmailProperties();          // 验证邮箱格式         if (!VerifyCodeUtil.checkEmail(email)) {             throw new BusinessException(ResultEnum.EMAIL_FORMAT_ERROR);         }          // 生成或获取验证码         String captcha = getCaptcha(email);          // 生成邮件内容         String content = generateEmailContent(captcha);          // 发送邮件         List list = Collections.singletonList(email);         sendEmail(list, content);     }      /**      * 判断邮件配置是否完整      */     private void validateEmailProperties() {         if (emailProperties.getUser() == null || emailProperties.getPassword() == null || emailProperties.getFrom() == null || emailProperties.getHost() == null || emailProperties.getPort() == null) {             throw new BusinessException(ResultEnum.EMAIL_VERIFICATION_CODE_CONFIGURATION_EXCEPTION);         }     }      /**      * 获取验证码      *      * @param email 邮箱地址,用于生成和存储验证码。      * @return {@link String} 返回生成的验证码。      */     private String getCaptcha(String email) {         // 根据邮箱生成Redis键名         String redisKey = CAPTCHA_CODE + email;         // 尝试从Redis获取现有的验证码         Object oldCode = redisUtils.get(redisKey);         if (oldCode == null) {             // 如果验证码不存在,生成新的验证码             String captcha = VerifyCodeUtil.generateVerifyCode();             // 将新生成的验证码存储到Redis,并设置过期时间             boolean saveResult = redisUtils.set(redisKey, captcha, emailProperties.getExpireTime());             if (!saveResult) {                 // 如果存储失败,抛出异常                 throw new RedisException(MessageConstant.REDIS_SERVICE_EXCEPTION_VERIFICATION_CODE_SAVE_FAILED);             }             return captcha;         } else {             // 如果验证码存在,重置其在Redis中的过期时间             boolean expireResult = redisUtils.expire(redisKey, emailProperties.getExpireTime());             if (!expireResult) {                 throw new RedisException(MessageConstant.RESET_VERIFICATION_CODE_FAILED);             }             return String.valueOf(oldCode);         }     }       /**      * 生成邮件内容      * @param captcha 验证码      * @return {@link String } 邮件内容      */     private String generateEmailContent(String captcha) {         Context context = new Context();         context.setVariable("verifyCode", Arrays.asList(captcha.split("")));         return templateEngine.process("EmailVerificationCode.html", context);     }      /**      * 发送邮件      * @param list      * @param content 邮件内容      */     private void sendEmail(List list, String content) {         MailAccount account = createMailAccount();         try {             Mail.create(account)                     .setTos(list.toArray(new String[0]))                     .setTitle(MessageConstant.EMAIL_VERIFICATION_CODE)                     .setContent(content)                     .setHtml(true)                     .setUseGlobalSession(false)                     .send();         } catch (Exception e) { // 捕获更广泛的异常             throw new BusinessException(ResultEnum.EMAIL_SENDING_EXCEPTION);         }     }      /**      * 创建邮件账户      * @return {@link MailAccount } 邮件账户      */     private MailAccount createMailAccount() {         MailAccount account = new MailAccount();         account.setAuth(true);         account.setHost(emailProperties.getHost());         account.setPort(emailProperties.getPort());         account.setFrom(emailProperties.getFrom());         account.setUser(emailProperties.getUser());         account.setPass(emailProperties.getPassword());         account.setSslEnable(true);         account.setStarttlsEnable(true);         return account;     }  } 

        测试


        参考文章

        邮件工具-MailUtil | Hutool

        手把手教你通过SpringBoot实现邮箱注册码验证_springboot+vue简单实现邮箱注册-CSDN博客

        springboot实现邮箱验证码功能_springboot邮箱验证码-CSDN博客

        SpringBoot 发送邮箱验证码(HTML模板)-阿里云开发者社区 (aliyun.com)

上一篇:气泡咖啡怎么做?

下一篇:年字五笔输入法打法详解,轻松掌握五笔输入技巧