【Springboot实用功能开发】发送QQ邮件以及邮件验证码对话框

news2024/12/24 2:43:33

文章目录

  • 参考博客
  • 1. 发送一封QQ邮件
    • 添加Maven依赖
    • QQ邮箱开启POP服务
    • 配置application.properties文件
    • Controller层
    • 编写 vue前端(也可以直接省略使用PostMan测试接口)
  • 2. 做一个发送邮件验证的对话框


参考博客

  1. vue实现验证码倒计时功能
  2. SpringBoot实现邮箱发送验证码(QQ,163等同理)

1. 发送一封QQ邮件

该模块使用Controller方法发送邮件给用户,用户将会在QQ邮箱中收到6位验证码

添加Maven依赖

 <dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-mail</artifactId>
 </dependency>

QQ邮箱开启POP服务

进入QQ邮箱界面, 打开邮箱–设置–账户
在这里插入图片描述
找到POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务如果没有开启,选择管理服务
在这里插入图片描述

点击进入后,点击“生成授权码”,后面按照QQ邮箱提示的操作,把授权码复制下来,后期会在项目配置文件中配置。
在这里插入图片描述

需要发送手机短信给QQ邮箱,然后才能生成QQ邮箱授权码
生成的授权码就是application.properties中的email.password值,application.properties具体内容如下:

配置application.properties文件

# # smtp用户名
spring.mail.username= #写绑定授权码的QQ邮箱,一般做邮箱发送测试就是写你自己的邮箱。
# # 服务授权码
spring.mail.password=  # 输入QQ邮箱给你的授权码,这个授权码要和上面的邮箱对应。
#smtp服务器,下面的其实都不用变
spring.mail.host=smtp.qq.com
spring.mail.properties.mail.smtp.ssl.enable=true
# 默认的邮件编码为UTF-8
spring.mail.default-encoding=UTF-8

Controller层

Spring邮箱验证测试类,尽量不要使用测试类,即使用@Test注解的测试方法测试。容易出现空指针异常。测试邮箱发送可以使用Controller方法

最后我们使用PostMan进行接口测试:
Controller类如下:

import com.feng.generation_design.entity.ApiResult;
import com.feng.generation_design.util.ApiResultHandler;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.web.bind.annotation.*;
@RestController
public class EmailController {
    //存储随机生成的校验码
    private String cdoe_store = null;
    @Autowired(required = false)
    private JavaMailSender sender; // 引入Spring Mail依赖后,会自动装配到IOC容器    
@GetMapping("/send")
    public ApiResult sendEmail() {
        String code = (Math.random() + "").substring(2, 8);	//生成6位随机数
        cdoe_store = code;
        String email = "xxx@qq.com";	//你想发给哪个邮箱
        SimpleMailMessage message = new SimpleMailMessage();
        message.setSubject("来自题库系统的提示"); // 发送邮件的主题
        message.setText("您好,您正在操作敏感信息,需要核验您的身份,您收到的验证码为:" + code); // 邮件的内容
        message.setTo(email); // 指定要接收邮件的用户邮箱账号
        message.setFrom("xxx@qq.com"); // 邮件发送方,也就是配置文件中的邮件地址。
        sender.send(message); // 调用send方法发送邮件
        return ApiResultHandler.buildApiResult(200, "邮件发送成功!", null);
}

关于@Autowired(required=false)的使用

打开PostMan,我们对接口进行测试,选择GET方式,并输入url:localhost:8080/send,不传入任何参数,点击"Send".

在这里插入图片描述


上面其实用PostMan就可以直接看到请求结果了,用户也能接受到邮件。但是为了可视化性更好,我们编写一个具有发送邮件功能的按钮,请求成功后会有提示。


前端使用vue,做一个简单的发送邮件请求的按钮。

编写 vue前端(也可以直接省略使用PostMan测试接口)

<template>
  <div>
    <el-button @click="sendEmail()" type="text" size="large"
      >生成邮件</el-button
    >
  </div>
</template>
<script>
export default {
  data() {
    return {};
  },
  methods: {
    sendEmail() {
      console.log("执行");
      //如果你的项目中使用cookies存储用户信息,可以使用当前用户存在系统cookie中的email值 作为邮件接收对象。
      //   let teacher_email = this.$cookies.get("c_email");

      this.$axios({
        url: `/api/send`,
      })
        .then((res) => {
          if (res.status === 200) {
            console.log(res);
            this.$message({
              type: "success",
              message: "邮件发送成功,请注意查收!",
            });
          }
        })
        .catch((error) => {
        console.log("打印出错信息")
        console.log(error)
          this.$message.error("邮件发送失败!!");
        });
    },
  },
};
</script>
<style></style>

有人可能会问,上面的/api啥意思,这个其实是在前端定义的,这里我就省略不写定义的地方了。这里实际上是对localhost:8088端口号的另称,不然前端的请求都要加上个localhost:8088得多麻烦!

上面UI用的是ElementU控件。写得很简单。
在这里插入图片描述
上面写的是text形式的按钮。点击后,如果请求数据成功,会提示:
在这里插入图片描述

邮件长这样:
在这里插入图片描述


其实这里可能会有小伙伴问,为什么这边是res.status呢?其实这里需要具体看,后端传过来的返回数据格式是什么样的。我们打开控制台(F12),(输出已经定义在我上面写的方法里了。)可以发现后端返回的数据如下:
在这里插入图片描述

res下面有status属性,所以我们前端如果想要获取到status,就用res.status来接收,200代表数据请求成功。
如果不清楚前端如何接收,可以在前端使用console.log(res);或者看看控制台输出的内容是什么。根据控制台打印的属性名获取即可。

2. 做一个发送邮件验证的对话框

该对话框代码来自原作者:@李优秀,原文博客:vue实现验证码倒计时功能

在原有的仅有倒计时功能的对话框基础上,现在做一个简单的验证码接收对话框,点击 发送验证码 后,系统发送验证码给用户,在倒计时过程中用户不能再次请求发送验证码请求。

业务场景如下:
在这里插入图片描述

在这里插入图片描述
上面的删除确认对话框就不展示了,现在直接点击“删除” 触发对话框。
代码如下:

<template>
  <div>
    <el-button @click="sendEmail()" type="text" size="large">生成邮件</el-button>
    <el-button @click="deleteIt()" type="text" size="large">删除题库</el-button>
    <!-- 点击删除后发送验证码确认 -->

    <el-dialog title="系统验证" :visible.sync="centerDialogVisible" width="40%" center>
      <br />
      <span class="warning_info"
        >您正在操作敏感信息,系统需要确认您为本人操作!系统已发送验证码至您邮箱,请注意查收!</span
      ><br /><br /><br />
      <div class="input_examcode_style">
        验证码:<el-input
          v-model="input_email_code"
          style="width: 40%"
          placeholder="请输入六位数验证码"
        ></el-input>

        <el-button
          v-bind:class="{ grey: isGrey, blue: !isGrey }"
          v-bind:disabled="dis"
          type="primary"
          @click="getCode"
        >
          <span v-if="show">发送验证码</span>
          <span v-else>重新发送({{ count }}s)</span>
        </el-button>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="centerDialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="submitExamCode()">提交</el-button>
      </span>
    </el-dialog>
  </div>
</template>
<script>
export default {
  data() {
    return {
      input_email_code: "",
      centerDialogVisible: false,
      // 邮件发送
      centerDialogVisible: false,
      dis: false,
      show: true,
      isGrey: false, //按钮样式
      timer: null, //设置计时器,
      count: "",
      //邮件发送
    };
  },
  methods: {
    getCode() {
      this.sendEmail();
      let TIME_COUNT = 60;
      if (!this.timer) {
        this.count = TIME_COUNT;
        this.isGrey = true;
        this.show = false;
        this.dis = true;
        this.timer = setInterval(() => {
          if (this.count > 0 && this.count <= TIME_COUNT) {
            this.count--;
          } else {
            this.dis = false;
            this.isGrey = false;
            this.show = true;
            clearInterval(this.timer);
            this.timer = null;
          }
        }, 1000);
      }
    },

    deleteIt() {
      console.log("删除");
      this.centerDialogVisible = true;
    },
    sendEmail() {
      console.log("执行");
      //如果你的项目中使用cookies存储用户信息,可以使用当前用户存在系统cookie中的email值 作为邮件接收对象。
      //   let teacher_email = this.$cookies.get("c_email");
      this.$axios({
        url: `/api/Email/send`,	//注意这个改成自己的接口URL
      })
        .then((res) => {
          if (res.status === 200) {
            console.log(res);
            this.$message({
              type: "success",
              message: "邮件发送成功,请注意查收!",
            });
          }
        })
        .catch((error) => {
          console.log("错误信息如下:");
          console.log(error);
          this.$message.error("邮件发送失败!!");
        });
    },
    submitExamCode() {
      let input = this.input_email_code;
      console.log("您输入的验证码为:" + this.input_email_code);
       this.$axios({
		...
		后续提交逻辑请求
		})
      this.input_email_code = null;
      this.centerDialogVisible = false;
    },
  },
};
</script>
<style>
.selector {
  margin-left: 10%;
}
.tableStyle {
  margin-left: 10%;
  width: 100%;
}
.page {
  margin-top: 20px;
  display: flex;
  justify-content: center;
  align-items: center;
}
.dialog_content {
  margin-left: 20%;
}
.grey {
  background-color: #edeef1;
  border-color: #edeef1;
  color: #666;
  width: 30%;
}
.blue {
  background-color: #64a0dd;
  border-color: #64a0dd;
}
.input_examcode_style {
  margin-left: 20%;
}
.warning_info {
  font-family: "华文中宋";
  font-size: 20px;
}
</style>

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

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

相关文章

会讲ppt的技术人,平均薪资多30%以上!

一场好的技术分享&#xff0c;可以用“有趣有料”四个字来形容&#xff0c;那么如何才能做到有趣又有料呢&#xff1f;结合我的经历&#xff0c;做了一些总结。 2015年&#xff0c;我出版《技术管理之巅》以后&#xff0c;先后收到QCon、CSDN、IT168等业界知名技术大会的邀请担…

大手笔!吴恩达一口气开放了 3 个 AIGC 教程。。

公众号关注 “GitHubDaily” 设为 “星标”&#xff0c;每天带你逛 GitHub&#xff01; 一个月前&#xff0c;DeepLearning.ai 创始人吴恩达与 OpenAI 开发者 Iza Fulford 联手推出了一门面向开发者的技术教程&#xff1a;《ChatGPT 提示工程》。 该教程总共分为 9 个章节&…

编码器-解码器 | 基于 Transformers 的编码器-解码器模型

基于 transformer 的编码器-解码器模型是 表征学习 和 模型架构 这两个领域多年研究成果的结晶。本文简要介绍了神经编码器-解码器模型的历史&#xff0c;更多背景知识&#xff0c;建议读者阅读由 Sebastion Ruder 撰写的这篇精彩 博文。此外&#xff0c;建议读者对 自注意力 (…

PYtriton:从Python提供的Triton Inference Server

env sudo docker run -it --shm-size 8gb --rm --gpusall -p 8126:8000 -v ${PWD}:/test nvcr.io/nvidia/pytorch:23.04-py3 bash sudo docker run -it --shm-size 8gb --rm --gpusall -v ${PWD}:/test nvcr.io/nvidia/pytorch:23.04-py3 bash 服务端Docker : sudo docker ru…

chatgpt赋能python:Python关闭应用程序:如何安全、有效地终止进程

Python关闭应用程序&#xff1a;如何安全、有效地终止进程 Python是一种流行的编程语言&#xff0c;广泛应用于各种领域和行业。在实际的开发工作中&#xff0c;我们常常需要处理进程的启动和终止问题。无论是在测试环境还是在生产环境中&#xff0c;安全有效地终止进程都是至…

一个job问题引出的Oracle官方文档的差错

同事提了个问题&#xff0c;PLSQL Developer连接Oracle 11g创建编辑job都正常&#xff0c;但是相同的PLSQL Developer连接Oracle 19c能创建job&#xff0c;但是选择编辑&#xff0c;就会提示如下日期格式错误&#xff0c; 看了一些资料&#xff0c;有的说是操作系统和Oracle的日…

【实用篇】RabbitMQ

文章目录 RabbitMQ1.初识MQ1.1.同步和异步通讯1.1.1.同步通讯1.1.2.异步通讯 1.2.技术对比&#xff1a; 2.快速入门2.1.安装RabbitMQ2.1.1.单机部署下载镜像安装MQ 2.2.RabbitMQ消息模型2.3.导入Demo工程2.4.入门案例2.4.1.publisher实现2.4.2.consumer实现 2.5.总结 3.SpringA…

【服务器】树洞外链搭建图床操作系统

文章目录 1.前言2. 树洞外链网站搭建2.1. 树洞外链下载和安装2.2 树洞外链网页测试2.3 cpolar的安装和注册 3. 本地网页发布3.1 Cpolar临时数据隧道3.2 Cpolar稳定隧道&#xff08;云端设置&#xff09;3.3 Cpolar稳定隧道&#xff08;本地设置&#xff09; 4. 公网访问测试5. …

Java on VS Code 5月更新|性能、用户体验改进以及 Spring Boot 集成

作者&#xff1a;Nick Zhu - Senior Program Manager, Developer Division at Microsoft 排版&#xff1a;Alan Wang 大家好&#xff0c;欢迎来到 Visual Studio Code Java 的 5 月更新&#xff01;在本月的博客中&#xff0c;我们有大量新功能&#xff0c;涵盖性能改进、用户体…

完成MQTT客户端,前几年的欠债还上了

最近有点儿忙&#xff0c;努力方向很重要&#xff0c;最近VFP硬件开发课已完结&#xff0c;顺便补一下前面欠的MQTT完整客户端&#xff0c;支持QOS0,OQS1,LAST WILLMSG. QOS2的支持看有需求再说了。 猫猫的心里话 加菲猫的VFP|狐友会社群接收投稿啦 加菲猫的VFP&#xff0c;用…

Python Playwright API使用实例详解

下方查看历史精选文章 重磅发布 - 自动化框架基础指南pdfv1.1大数据测试过程、策略及挑战 测试框架原理&#xff0c;构建成功的基石 在自动化测试工作之前&#xff0c;你应该知道的10条建议 在自动化测试中&#xff0c;重要的不是工具 什么是 Playwright Playwright 是一个 Nod…

38从零开始学Java之封装到底是咋回事?

作者&#xff1a;孙玉昌&#xff0c;昵称【一一哥】&#xff0c;另外【壹壹哥】也是我哦 千锋教育高级教研员、CSDN博客专家、万粉博主、阿里云专家博主、掘金优质作者 前言 我们知道&#xff0c;Java是面向对象的编程语言。关于面向对象的概念&#xff0c;壹哥在之前的文章中…

【linux】进程: systemd、systemctl

状态 R —— 运行S&#xff08;TASK_INTERRUPTIBLE&#xff09; —— 等待&#xff0c;可中断&#xff0c;IOD&#xff08;TASK_UNINTERRUPTIBLE&#xff09; —— 等待&#xff0c;不可中断K&#xff08;TASK_KILLABLE&#xff09; —— 等待&#xff0c;可删除&#xff0c;I…

chatgpt赋能python:Python内置函数大全表

Python 内置函数大全表 Python 是一种强大的编程语言&#xff0c;拥有许多有用的内置函数。这些函数可以在编写 Python 代码时大大简化开发人员的工作流程。本文提供了一张Python内置函数的大全表&#xff0c;以及每个函数的简要说明。 内置函数列表 以下是 Python 的内置函…

Elasticsearch:在 Elasticsearch 中使用 NLP 和矢量搜索增强聊天机器人功能

作者&#xff1a;Priscilla Parodi 会话界面已经存在了一段时间&#xff0c;并且作为协助各种任务&#xff08;例如客户服务、信息检索和任务自动化&#xff09;的一种方式而变得越来越流行。 通常通过语音助手或消息应用程序访问&#xff0c;这些界面模拟人类对话&#xff0c;…

众议院压倒性通过!

* * * 原创&#xff1a;刘教链 * * * 号外&#xff1a;今天在小号“刘教链Pro”发表了一篇《大V出货了》&#xff0c;欢迎关注“刘教链Pro”并阅读。 * * * 隔夜比特币回升至27k上方。 万众瞩目的美债危机到了千钧一发之际。继周日美国总统拜登和众议院议长麦卡锡初步达成口头…

618特辑 | 人到中年的品质生活,是我对自己的最大尊重

点击文末“阅读原文”即可参与节目互动 剪辑、音频 / 卷圈 运营 / SandLiu 卷圈 监制 / 姝琦 文案 / 粒粒 封面 / 姝琦midjourney 产品统筹 / bobo 场地支持 / 声湃轩北京录音间 不知从什么时候开始&#xff0c;我们开始高亮“实用主义”的生活态度&#xff0c;一切以…

FPGA PAL视频BT656解码Video Processing Subsystem去隔行 TW2867采集 提供工程源码和技术支持

目录 1、前言2、我这里已有的PAL视频解码方案3、模拟视频概述4、模拟视频颜色空间5、逐行与隔行6、BT656数据与解码BT656数据格式BT656数据解码 7、TW2867芯片解读与配置TW2867芯片解读TW2867芯片配置TW2867时序分析 8、设计思路与框架9、vivado工程详解Block Design设计SDK设计…

c++实现产品功能(简单基础功能)

通过c++实现公司产品功能,要求能在VS和CB上完美运行,实现的功能基础简单 #include <iostream> #include <string>// 摄像机类 class Camera { public:// 成员函数:拍摄照片void takePhoto() {std::cout << "Take a photo." << std::endl;…

六一儿童节,小灰给大家准备了特别的礼物!

大家好&#xff0c;我是程序员小灰。 熟悉小灰的朋友们都知道&#xff0c;小灰比较擅长写作&#xff0c;却并不善于口头表达。 但是&#xff0c;在2023年&#xff0c;小灰决定搞一件大事情&#xff0c;与我的团队成员共同组建《小灰AI共创汇》。我们这个共创汇的目标&#xff0…