springboot模板整合(四)邮箱验证

引包

<!--引入thymeleaf框架-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>
        <!--引入邮箱-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-mail</artifactId>
        </dependency>

        <!--引入freemarker框架-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-freemarker</artifactId>
        </dependency>

邮箱

邮箱工具类

编写一个邮箱工具类

package com.example.springboot_template01.common;

import com.example.springboot_template01.SpringbootTemplate01Application;
import com.example.springboot_template01.entity.PersonForm;
import freemarker.template.Configuration;
import freemarker.template.Template;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.FileSystemResource;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

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

/**
 * 邮件工具类,发送邮件
 */
@Component
public class EmailUtil {
    //通过JavaMailSenderImpl中的无参构造方法,从而调用MailSenderPropertiesConfiguration类,通过mailSender方法中this.applyProperties即可
    @Autowired
    private JavaMailSenderImpl mailSender;

    @Autowired
    TemplateEngine templateEngine;

    /**
     * 发送包含简单文本的邮件
     */
    public  String  sendTxtMail(String email,String message) {
        SimpleMailMessage simpleMailMessage = new SimpleMailMessage();
        // 设置收件人邮箱
        simpleMailMessage.setTo(new String[] {email});
        //设置寄件人邮箱
        simpleMailMessage.setFrom("3496552199@qq.com");
        simpleMailMessage.setSubject("验证码校验");
        simpleMailMessage.setText("你的验证码为"+message+"验证码的有效期为1分钟");
        // 发送邮件
        mailSender.send(simpleMailMessage);

        return "邮件已发送";
    }

    /**
     * 发送包含HTML文本的邮件
     * @throws Exception
     */
    public void sendHtmlMail() throws Exception {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage);
        mimeMessageHelper.setTo("2731577548@qq.com");
        mimeMessageHelper.setFrom("3496552199@qq.com");
        mimeMessageHelper.setSubject("Spring Boot Mail 邮件测试【HTML】");

        StringBuilder sb = new StringBuilder();
        sb.append("<html><head></head>");
        sb.append("<body><h1>spring 邮件测试</h1><p>hello!this is spring mail test。</p></body>");
        sb.append("</html>");

        // 启用html
        mimeMessageHelper.setText(sb.toString(), true);
        // 发送邮件
        mailSender.send(mimeMessage);

        System.out.println("邮件已发送");

    }

    /**
     * 发送包含内嵌图片的邮件
     * @throws Exception
     */
    public void sendAttachedImageMail() throws Exception {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        // multipart模式
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true);
        mimeMessageHelper.setTo("2731577548@qq.com");
        mimeMessageHelper.setFrom("3496552199@qq.com");
        mimeMessageHelper.setSubject("Spring Boot Mail 邮件测试【图片】");

        StringBuilder sb = new StringBuilder();
        sb.append("<html><head></head>");
        sb.append("<body><h1>spring 邮件测试</h1><p>hello!this is spring mail test。</p>");
        // cid为固定写法,imageId指定一个标识
        sb.append("<img src=\"cid:imageId\"/></body>");
        sb.append("</html>");

        // 启用html
        mimeMessageHelper.setText(sb.toString(), true);

        // 设置imageId
        FileSystemResource img = new FileSystemResource(new File("D:/image/7.png"));
        mimeMessageHelper.addInline("imageId", img);

        // 发送邮件
        mailSender.send(mimeMessage);

        System.out.println("邮件已发送");
    }

    /**
     * 发送包含附件的邮件
     * @throws Exception
     */
    public void sendAttendedFileMail() throws Exception {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        // multipart模式
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8");
        mimeMessageHelper.setTo("2731577548@qq.com");
        mimeMessageHelper.setFrom("3496552199@qq.com");
        mimeMessageHelper.setSubject("Spring Boot Mail 邮件测试【附件】");

        StringBuilder sb = new StringBuilder();
        sb.append("<html><head></head>");
        sb.append("<body><h1>spring 邮件测试</h1><p>hello!this is spring mail test。</p></body>");
        sb.append("</html>");

        // 启用html
        mimeMessageHelper.setText(sb.toString(), true);
        // 设置附件
        FileSystemResource img = new FileSystemResource(new File("D:/image/7.png"));
        mimeMessageHelper.addAttachment("image.png", img);

        // 发送邮件
        mailSender.send(mimeMessage);

        System.out.println("邮件已发送");
    }

    /**
     * 将一个html网页作为邮件内容发送,并通过thymeleaf框架实现页面内容的动态加载
     * @throws Exception
     */
    public void sendPage() throws Exception {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        // multipart模式
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8");
        mimeMessageHelper.setTo("2731577548@qq.com");
        mimeMessageHelper.setFrom("3496552199@qq.com");
        mimeMessageHelper.setSubject("Spring Boot Mail 邮件测试【附件】");
        Context context = new Context();
        context.setVariable("name", "李华");
        context.setVariable("age","000020");
        String process = templateEngine.process("ruZhi.html", context);
        mimeMessageHelper.setText(process,true);

        // 发送邮件
        mailSender.send(mimeMessage);

        System.out.println("邮件已发送");
    }

    /**
     * 将一个html网页作为邮件内容发送,并通过freeMarker框架实现页面内容的动态加载
     * @throws Exception
     */
    public void sendFreeMarkerPage() throws Exception {
        MimeMessage mimeMessage = mailSender.createMimeMessage();
        // multipart模式
        MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(mimeMessage, true, "utf-8");
        mimeMessageHelper.setTo("2731577548@qq.com");
        mimeMessageHelper.setFrom("3496552199@qq.com");
        mimeMessageHelper.setSubject("入职邀请函");
        //构建 Freemarker 的基本配置
        Configuration configuration = new Configuration(Configuration.VERSION_2_3_0);
        // 配置模板位置
        ClassLoader loader = SpringbootTemplate01Application.class.getClassLoader();
        configuration.setClassLoaderForTemplateLoading(loader, "templates");
        //加载模板
        Template template = configuration.getTemplate("freeMarker.html");
        PersonForm user = new PersonForm();
        user.setName("王飞");
        user.setAge(1001);
        StringWriter out = new StringWriter();
        //模板渲染,渲染的结果将被保存到 out 中 ,将out 中的 html 字符串发送即可
        template.process(user, out);
        mimeMessageHelper.setText(out.toString(),true);

        // 发送邮件
        mailSender.send(mimeMessage);

        System.out.println("邮件已发送");
    }
}

邮箱配置配置

在application.properties中添加

#email
spring.mail.host=smtp.qq.com
spring.mail.username=3496552199@qq.com
#授权码,不是密码
spring.mail.password=授权码
spring.mail.port=25
spring.mail.protocol=smtp
spring.mail.default-encoding=UTF-8

如何开启QQ邮箱的stamp?
QQ邮箱的授权码需要开启QQ邮箱的stamp服务才有,如何开启stamp服务,参看QQ邮箱开启pop3/stmp服务

生成随机验证码

下面是两种生成验证码的方式

package com.example.springboot_template01.common;


import com.example.springboot_template01.web.ConsumerController;

import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;

public class VerificationCode {
    /**
     * 通过code的值判断是多少位的验证码,通过每次获取的随机数,然后作为位置截取一个字符
     * @param code 表示验证码的位数,比如说4表示4位验证码
     * @return
     */
    public String resultSixCode(int code){
        String data = "0123456789qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM";
        String result = "" ;
        //System.out.println(data.substring(61, 62));
        for (int i = 0; i < code; i++) {
            //在字符串data的长度范围里,获取一个任意的整数,并拿到对应位置的字符
            int r = new Random().nextInt(data.length());
            result = result + data.substring(r,r+1);
        }
        return result;

    }

    /**
     * 通过将集合乱序排列后,抽取前code位最为随机验证码
     * @param code
     * @return
     */
    // 随机验证码
    public String achieveCode(int code) {  //由于数字1 和0 和字母 O,l 有时分不清,所有,没有字母1 、0
        String[] beforeShuffle= new String[] { "0","1","2", "3", "4", "5", "6", "7", "8", "9", "A", "B", "C", "D", "E", "F",
                "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "a",
                "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",
                "w", "x", "y", "z" };
        List list = Arrays.asList(beforeShuffle);//将数组转换为集合
        Collections.shuffle(list);  //打乱集合顺序
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < list.size(); i++) {
            sb.append(list.get(i)); //将集合转化为字符串
        }
        return sb.toString().substring(0, code);  //截取字符串第1到code位置的字符串
    }




}

html页面

创建js文件夹以及创建js文件

文件的目录如下图所示:
在这里插入图片描述
js文件的内容


var tempTime = 1;
var timer;
/*获取验证码*/
function send(obj){
    var email = $("#consumer_email").val();
    if(email==null||email ==""){
        alert("邮箱不能为空");
        return null;
    }


    $.ajax({
        url:"sendCode",
        type:"get",
        data:{
            "email":email
        },
        error:function(){
            console.log("查询出错");
        },
        success:function(){
            alert("发送成功");
            $("#send").attr("disabled",true);
            timer = window.setInterval("changeButton()",1000);

        }

    })

}
/*定时事件*/
function changeButton(){
    if(tempTime>=60){
        tempTime = 1;
        clearTimeout(timer);
        $("#send").attr("disabled",false);
        $("#send").val(null);
        $("#send").val("免费获取验证码");
    }else{
        tempTime++;
        var c =  60-tempTime;
        $("#send").val(null);
        $("#send").val("还需等待"+c+"秒");

    }
}


html页面

<!DOCTYPE html>
<html lang="en" xmlns:th="https://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script type="text/javascript"  src="../static/js/jquery-3.4.1.js" ></script>
    <script type="text/javascript"  src="../static/js/register.js" ></script>
    <!--th:href="@{../static/js/jquery.3.4.1.js}"-->
</head>
<body>
<div>

    <div><h1>注册</h1></div>
    <form action="#" th:action="@{/checkCode}"  method="post">
    <div><span>呢称:</span><input name="consumer_other_name" id="consumer_other_name"/></div>
    <div><span>密码</span><input name="consumer_password" id="consumer_password"/></div>
    <div><span>邮箱</span><input name="consumer_email" id="consumer_email"/></div>
    <div>
        <span>验证码</span>
        <input name="validCode" id="validCode"  />

    </div>
    <div><button type="submit"  id="add" >提交</button></div>
    <span th:text="${message}"></span>
    <span id="htmlResult"></span>
    </form>
    <input type="button" id="send" value="免费获取验证码" onclick="send(this)" />
</div>
</body>

</html>

编辑接口

   package com.example.springboot_template01.web;

import com.example.springboot_template01.common.EmailUtil;
import com.example.springboot_template01.common.VerificationCode;
import com.example.springboot_template01.dao.ConsumerDao;
import com.example.springboot_template01.entity.Consumer;
import com.example.springboot_template01.service.ConsumerService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Controller
@Api(value = "ConsumerController",tags = "用户接口")
public class ConsumerController {
    private static Map<String,Long> map = new HashMap<String,Long>();

    @Autowired
    private ConsumerService consumerService;
    @Autowired
    private ConsumerDao consumerDao;
    @Autowired
    private EmailUtil emailUtil;

    @ApiOperation(value = "selectConsumerAll",notes = "无条件不分页查询所有的用户")
    @GetMapping("/selectConsumerAll")
    @ResponseBody
    public String selectConsumerAll(){
        return consumerService.selectAll();
    }

    @ApiOperation(value = "login",notes = "用户登录校验")
    @PostMapping("/login")
    public String login(Consumer consumer, Model model){
        if(consumer.getConsumer_id()==""||consumer.getConsumer_password()==""){
            model.addAttribute("message", "用户名和密码均不能为空");
            return "login";
        }
        Consumer c = consumerDao.selectByName(consumer);
        if(c != null){
            c = consumerDao.selectByPassword(consumer);
            if(c!=null){
                model.addAttribute("message", "登录成功");
                return "index";
            }else{
                model.addAttribute("message", "密码错误");
            }
        }else{
            model.addAttribute("message", "该用户名不存在");
        }
        return "login";
    }

    @ApiOperation(value = "/",notes = "拦截默认访问,跳转到登录页")
    @GetMapping("/")
    public String index(){
        return "login";
    }

    /**
     * 方便静态页面的跳转,避免拦截swagger.html页面,所以我们只是拦截URI中包含
     * @param request
     * @return
     */
    @ApiOperation(value = "/*.html",notes = "拦截所有直接访问的html页面,一般用于页面链接的跳转")
    @GetMapping("/register.html")
    public String resultPage( HttpServletRequest request) {
        //获取请求的路径
        String temp = request.getRequestURI();
        //获取跳转页面的名称
        String result = temp.substring(temp.lastIndexOf("/")+1,temp.lastIndexOf(".html"));
        return  result;
        //上面三句不执行,直接执行返回null,也可以实现页面的跳转
        //return null;
    }


    /**
     * 发送验证码,并将超过60秒的验证码删除
     * @param email
     * @return
     */
    @GetMapping("/sendCode")
    public String sendCode(String email, Model model){
        if(email == null ||email.equals("")){
            model.addAttribute("message", "邮箱内容不能为空");
            return "register";
        }
        if((email.indexOf("@") <=0) || (email.indexOf(".com") <= 0)){
            model.addAttribute("message", "邮箱内容格式不对");
            return "register";
        }
        String code = new VerificationCode().achieveCode(6);
        map.put(code, System.currentTimeMillis());
        Long currentTime = System.currentTimeMillis();
        Iterator<Map.Entry<String, Long>> its = map.entrySet().iterator();
        for (Iterator<Map.Entry<String, Long>> it = map.entrySet().iterator(); it.hasNext(); ) {
            Map.Entry<String, Long> item = it.next();//此句不能少,否则,删除当前节点,指针无法找到下一节点
            //如果验证码的时间超过60秒,删除该验证码
            if(item.getValue() + 60000 < currentTime){
                it.remove();
            }
        }
        emailUtil.sendTxtMail(email,code);
        return  "register";
    }

    /**
     * 校验验证码是否正确,并测试当前邮箱是否已经注册过了
     * @param consumer
     * @param validCode
     * @param model
     * @return
     */
    @PostMapping("/checkCode")
    public String checkCode(Consumer consumer,String validCode,Model model){
        Consumer consumerEmailExit = consumerDao.selectConsumerEmailExit(consumer);
        if(consumerEmailExit != null){
            model.addAttribute("message", "该邮箱已经注册过了");
            return "register";
        }else{
            if(map.get(validCode) != null){
                model.addAttribute("message", "注册成功,请登录");
                return "index";
            }else{
                model.addAttribute("message", "验证码错误");
                return "register";
            }

        }
    }
}

测试

在这里插入图片描述
输入邮箱后,点击“免费获取验证码”按钮,点击后的效果图如下,此时输入的邮箱应该已经收到验证码了
在这里插入图片描述
输入昵称,密码,验证码
在这里插入图片描述
点击提交,跳转到了指定页面,如下图
在这里插入图片描述

源码

源码网址

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值