springboot使用TemplateEngine发送HTML邮箱验证码

springboot使用TemplateEngine发送HTML邮箱验证码


和别的博主没什么不一样,但是别的博主都没有贴出来TemplateEngine使用是html模板的路径设置这里贴出

并附上完整教程

pom.xml依赖

        <!--  邮箱maven    -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>
        <!--  TemplateEngine maven    -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf</groupId>
            <artifactId>thymeleaf-spring5</artifactId>
        </dependency>
        <dependency>
            <groupId>org.thymeleaf.extras</groupId>
            <artifactId>thymeleaf-extras-java8time</artifactId>
        </dependency>

application.yml设置

此处使用QQ邮箱,其他邮箱自行百度

  mail:
    host: smtp.qq.com    #邮箱服务器地址 此处为QQ邮箱的
    username: xxx@qq.com   #邮箱账号
    password: xxxxxx            #邮箱密码,此处为QQ邮箱授权码,下图有介绍
    default-encoding: utf-8    #默认编码
    from: xxx@qq.com  #邮件发件人
    properties.mail.smtp.starttls.enable: true
    properties.mail.smtp.starttls.required: true
    properties.mail.smtp.ssl.enable: true
  thymeleaf:
    prefix: classpath:/mail/  #prefix:指定模板所在的目录
    check-template-location: true  #check-tempate-location: 检查模板路径是否存在
    cache: false  #cache: 是否缓存,开发模式下设置为false,避免改了模板还要重启服务器,线上设置为true,可以提高性能。
    suffix: .html
    mode: HTML5

存放模板地址以及格式
文
开启QQ邮箱授权码:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

模板格式
想要美观一点可以自己重新写一个

<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        h1{
            color: red;
        }
    </style>
</head>
<body>
尊敬的用户,您好:<br><br>
本次请求的邮件验证码为:<br>
<h1>[[${message}]]</h1>
本验证码5分钟内有效,请及时输入。(请勿泄露此验证码)<br>
如非本人操作,请忽略该邮件。<br>
(这是一封自动发送的邮件,请不要直接回复)<br>
</body>
</html>

工具类

此处使用了SecureRandom是由于Random创建的是伪随机数,可被破解,具体可看一下下面文章

Random和SecureRandom详解
Java 随机数生成器 Random & SecureRandom 原理分析

package com.example.springbootservicepractice.util;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.security.SecureRandom;


/**
 * @author 凌殇
 * @date 2022年03月08日 15:40
 */

public class ValidateCodeUtil {
	//Random 不是密码学安全的,加密相关的推荐使用 SecureRandom
    private static Random RANDOM = new SecureRandom();

    private static final String randomString = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWSYZ";
    private final static String token = "MAILTOKEN";
    /**
     * 生成6位随机数字
     * @return 返回6位数字验证码
     */
    public String generateVerCode(HttpServletRequest request, HttpServletResponse response) {
        HttpSession session = request.getSession();
        char[] nonceChars = new char[6];
        for (int index = 0; index < nonceChars.length; ++index) {
            nonceChars[index] = randomString.charAt(RANDOM.nextInt(randomString.length()));
        }
        //移除之前的session中的验证码信息
        session.removeAttribute(token);
        //将验证码放入session
        session.setAttribute(token,new String(nonceChars));//设置token,参数token是要设置的具体值
        return new String(nonceChars);
    }

}


创建service接口以及实现类

附带邮箱验证码、邮箱发送html验证码、邮箱发送html以及附件

package com.example.springbootservicepractice.service;

import org.springframework.stereotype.Service;

@Service("iMailService")
public interface IMailService {
    /**
     * 发送邮件
     * @param receiver 邮件收件人
     * @param subject 邮件主题
     * @param verCode 邮件验证码
     */
    void sendEmailVerCode(String receiver, String subject, String verCode);

    /**
     * 发送HTML邮件
     *
     * @param to      收件人
     * @param subject 主题
     * @param content 内容
     */
    void sendHtmlMail(String to, String subject, String content);


    /**
     * 发送带附件的邮件
     *
     * @param to       收件人
     * @param subject  主题
     * @param content  内容
     * @param filePath 附件
     */
    void sendAttachmentsMail(String to, String subject, String content, String filePath);
}

package com.example.springbootservicepractice.service.impl;


import com.example.springbootservicepractice.service.IMailService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.MailSendException;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import javax.mail.internet.MimeMessage;
import java.io.File;

/**
 * @author 凌殇
 * @date 2022年03月08日 16:33
 */

@Slf4j
@Service
public class MailServiceImpl implements IMailService {

        @Autowired
        JavaMailSenderImpl mailSender;

        @Autowired
        TemplateEngine templateEngine;
        /**
         * 从配置文件中获取发件人
         */
        @Value("${spring.mail.username}")
        private String sender;

        /**
         * 邮件发送
         * @param receiver 收件人
         * @param subject 主题
         * @param verCode 验证码
         * @throws MailSendException 邮件发送错误
         */
        @Async
        public void sendEmailVerCode(String receiver, String subject, String verCode) throws MailSendException {
            SimpleMailMessage message = new SimpleMailMessage();
            message.setSubject("验证码");	//设置邮件标题
            message.setText("尊敬的用户,您好:\n"
                    + "\n本次请求的邮件验证码为:\n<span>" + verCode + "</span>,本验证码5分钟内有效,请及时输入。(请勿泄露此验证码)\n"
                    + "\n如非本人操作,请忽略该邮件。\n(这是一封自动发送的邮件,请不要直接回复)");	//设置邮件正文
            message.setTo(receiver);	//设置收件人
            message.setFrom(sender);	//设置发件人
            mailSender.send(message);	//发送邮件
        }

    /**
     * html邮件
     *
     * @param to      收件人
     * @param subject 主题
     * @param content 内容
     */
    @Override
    public void sendHtmlMail(String to, String subject, String content) {
        //获取MimeMessage对象
        MimeMessage message = mailSender.createMimeMessage();
        MimeMessageHelper messageHelper;
        try {
            messageHelper = new MimeMessageHelper(message, true);
            //邮件发送人
            messageHelper.setFrom(sender);
            //邮件接收人
            messageHelper.setTo(to);
            //邮件主题
            message.setSubject(subject);
            Context context = new Context();
            //设置传入模板的页面的参数 参数名为:id 参数随便写一个就行
            context.setVariable("message", content);
            //emailTemplate是你要发送的模板我这里用的是Thymeleaf
            String process = templateEngine.process("emailTemplate", context);
            //邮件内容,html格式
            messageHelper.setText(process, true);
            //发送
            mailSender.send(message);
            //日志信息
            log.info("邮件已经发送。");
        } catch (Exception e) {
            log.error("发送邮件时发生异常!", e);
        }
    }

    /**
     * 带附件的邮件
     *
     * @param to       收件人
     * @param subject  主题
     * @param content  内容
     * @param filePath 附件
     */
    @Override
    public void sendAttachmentsMail(String to, String subject, String content, String filePath) {
        MimeMessage message = mailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);
            helper.setFrom(sender);
            helper.setTo(to);
            helper.setSubject(subject);
            helper.setText(content, true);

            FileSystemResource file = new FileSystemResource(new File(filePath));
            String fileName = filePath.substring(filePath.lastIndexOf(File.separator));
            helper.addAttachment(fileName, file);
            mailSender.send(message);
            //日志信息
            log.info("邮件已经发送。");
        } catch (Exception e) {
            log.error("发送邮件时发生异常!", e);
        }


    }
}



controller类

package com.example.springbootservicepractice.controller;

import com.example.springbootservicepractice.service.IMailService;
import com.example.springbootservicepractice.util.ValidateCodeUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

/**
 * @author 凌殇
 * @date 2022年03月08日 16:50
 */

@RestController
public class EmailController {

    @Autowired
    IMailService iMailService;

    @PostMapping("/email")
    public void sendEmail(@RequestParam("emailAddress") String emailAddress,HttpServletRequest request, HttpServletResponse response, HttpSession session) {

        try {
            ValidateCodeUtil validateCode = new ValidateCodeUtil();
            iMailService.sendHtmlMail(emailAddress,"验证码", validateCode.generateVerCode(request,response));
            //获取存放在session域中的验证码
            String sessionCode= String.valueOf(session.getAttribute("MAILTOKEN")).toLowerCase();
            System.out.println("session里的验证码:"+sessionCode);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    @PostMapping("/emailCaptcha")
    public boolean getCheckCaptcha(@RequestParam("code") String code, HttpSession session) {

        try {
            // 获取存放在session域中的验证码  toLowerCase() 不区分大小写进行验证码校验
            String sessionCode= String.valueOf(session.getAttribute("MAILTOKEN")).toLowerCase();
            System.out.println("session里的验证码:"+sessionCode);
            String receivedCode=code.toLowerCase();
            System.out.println("用户的验证码:"+receivedCode);
            return !sessionCode.equals("") && !receivedCode.equals("") && sessionCode.equals(receivedCode);

        } catch (Exception e) {

            return false;
        }

    }
}

进行效验
postman发送请求
在这里插入图片描述

控制台输出结果

在这里插入图片描述
发送验证码效验请求
第一次错误尝试
在这里插入图片描述
第二次正确尝试

在这里插入图片描述

控制台输出结果
请添加图片描述

完成
请添加图片描述

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值