记录一下SpringBoot电子邮件发送这件事

起因:

        这次想做一个以电子邮件的方式来发送验证码给管理员,以便修改管理员密码。由于自己将本地环境部署的电子邮件案例测试通过后,便天真地以为能够上线,正常跑通了,但是由于是第一次接触这个电子邮箱,对其也是一知半解的,果然,踩坑了。

        在项目上线后,由于阿里云和腾讯云默认关闭25端口(要开启听说要申请),所以没办法,只能修改电子邮件的端口为SSL方式的另外两个端口(465或994),最终在一系列配置之后,总算是成功发送电子邮件了

电子邮箱功能添加流程

  • 添加相关依赖(我添加的是SpringBoot的starter依赖)

        <!--        电子邮件发送工具--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-mail</artifactId></dependency>
  • 添加邮箱配置

--- #短信配置
spring:mail:# 配置 SMTP 服务器地址host: smtp.163.com# 发送者邮箱username: ***(自己的邮箱)***# 配置密码注意是刚刚申请到的授权码password: ***(自己的授权码)***# 端口号 25或465/994(使用ssl时)port: 465# 默认的邮件编码为UTF-8default-encoding: UTF-8# 邮件协议protocol: smtp# 配置SSL 加密工厂properties:mail:smtp:auth: truerequired:enable: true# 设为true时 端口号设为 465 设为false时 端口号设为25ssl: enable: truesocketFactoryClass: javax.net.ssl.SSLSocketFactory#表示开启 DEBUG 模式邮件发送过程的日志会在控制台打印出来debug: true
  • 发送邮件

    • Controller 层
    @Autowiredprivate MailService mailService;    @PostMapping("/sendMail/{email}")public Result<String> sendMail(@PathVariable("email") String email) {// 校验邮箱格式是否正确boolean isEmail = Validator.isEmail(email);if (!isEmail) {throw new BusinessNewException(ErrorConstant.EMAIL_PATTERN_NOT_MATCH);}try {mailService.sendMail(email);return Result.ok("邮件发送成功");} catch (MessagingException e) {e.printStackTrace();return Result.failed("邮件发送失败");}}

  • Service层(为了方便,简写了)
    @Autowired(required = false)private JavaMailSender mailSender;@Resourceprivate StringRedisTemplate stringRedisTemplate;/*** 发送信息邮件* @param to 收件人* @throws MessagingException 异常*/public void sendMail(String to) throws MessagingException {// 使用hutool生成验证码// 创建一个LineCaptcha实例,设置长度(默认为4位)String captchaCode = RandomUtil.randomNumbers(6);if (Boolean.TRUE.equals(stringRedisTemplate.hasKey(RedisConstant.ADMIN_FORGOT_PASSWORD_KEY + to))) {throw new BusinessNewException("验证码已发送,请勿在一分钟内重复发送");}else{stringRedisTemplate.opsForValue().set(RedisConstant.ADMIN_FORGOT_PASSWORD_KEY + to, captchaCode, 60, TimeUnit.SECONDS);}MimeMessage message = mailSender.createMimeMessage();MimeMessageHelper helper = new MimeMessageHelper(message, true);//邮箱发送者helper.setFrom(userName);//收件人,可以为多个收件人,收件人之间用逗号隔开helper.setTo(to);// 邮箱标题helper.setSubject(EmailConstant.EMAIL_TITLE_FORGOT_PASSWORD);// 邮箱内容String emailContent = EmailConstant.EMAIL_PREFIX_CONTENT_FORGOT_PASSWORD +"您本次的验证码为:" + captchaCode + ",请在60秒内填写,否则验证码失效\n" +EmailConstant.EMAIL_SUFFIX_FORGOT_PASSWORD;helper.setText(emailContent, true);mailSender.send(message);}

        这里使用了RedisStringTemplate限制用户1分钟后才能重复发送。

  • 其他部分 

EmailConstant:
public interface EmailConstant {String EMAIL_TITLE_FORGOT_PASSWORD = "这里是电子邮件标题";String EMAIL_PREFIX_CONTENT_FORGOT_PASSWORD ="(电子邮件内容前缀)尊敬的管理员,\n" +"您收到这封邮件是因为您在***网站要通过邮件的方式找回密码,\n";String EMAIL_SUFFIX_FORGOT_PASSWORD = "(电子邮件内容后缀)如果您的邮箱没有收到邮件,请联系管理员,\n" ;
}
RedisConstant.ADMIN_FORGOT_PASSWORD_KEY
    String ADMIN_FORGOT_PASSWORD_KEY = "wx:admin:forget:";

总结

        在这过程中,我卡得最久的竟然是yum的配置,将“ssl: ” 那里的"enable" 写成了“enabled” (主要是阿里的通义灵码给我的提示,我直接tab了),导致一直没成功。看来还得多多学习,才能少出BUG 

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

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

相关文章

简单多状态dp问题----按摩师

面试题 17.16. 按摩师 - 力扣&#xff08;LeetCode&#xff09; 1、状态表示&#xff1a; dp[i]&#xff1a;从前i个顾客预约中&#xff0c;接收预约的最大总时长。 2、状态转移方程&#xff1a; 首先本题特别的地方在于&#xff1a;不能连续接收两个预约&#xff0c;即不能…

【绘图案例-复习昨天的内容 Objective-C语言】

一、先把这个昨天的内容复习一下 1.首先,昨天学了QQ案例, 然后呢,把这个“通讯录”做完了啊, 在这个里边儿, 通讯录里边儿,有这么几个: 1)开关处理的逻辑:打开“自动登录”,让“记住密码”也自动去打开,取消“记住密码”,“自动登录”也自动去关闭, 2)然后呢,…

FPGA高端项目:FPGA基于GS2971的SDI视频接收+纯verilog图像缩放+多路视频拼接,提供8套工程源码和技术支持

目录 1、前言免责声明 2、相关方案推荐本博已有的 SDI 编解码方案本方案的SDI接收转HDMI输出应用本方案的SDI接收图像缩放应用本方案的SDI接收HLS图像缩放HLS多路视频拼接应用本方案的SDI接收OSD多路视频融合叠加应用本方案的SDI接收HLS多路视频融合叠加应用本方案的SDI接收GTX…

MySQL Server架构概述

推荐&#xff1a;SQL语句执行顺序相关问题。 MySQL Server架构 分层概述 MySQL Server架构可抽象为3层。 连接层&#xff1a;验证用户名密码&#xff0c;认证成功后&#xff0c;获取当前账号的权限并缓存&#xff0c;并分配TCP连接池和线程池资源。处理层&#xff1a;实现核…

代码随想录算法训练营第三十七天|LeetCode738 单调递增的数字、LeetCode968 监控二叉树

738.单调递增的数字 思路&#xff1a;要求一个数字从第一位往后的大小是单调递增的&#xff0c;先把数字转换成字符串&#xff0c;然后从后往前逐位遍历&#xff0c;如果当前位比前一位小&#xff0c;则前一位--&#xff0c;从当前位往后都应该为9&#xff0c;因此记下当前位置…

VPN应用场景典型案例-匿名网关组网应用

​​​​​​组网需求 多个发起方使用动态接入互联网方式,如PPPoE拨号或者NAT转换,这种方式中,发起方每次使用的IP地址可能不一致,所以响应端无法使用指定对端IP地址方式,匿名网关一端不指定对端IP,通过ID识别对端身份建立IPSec隧道,实现公司间内部网络的安全通信。 典…

去电脑维修店修电脑需要注意什么呢?装机之家晓龙

每当电脑出现故障时&#xff0c;你无疑会感到非常沮丧。 如果计算机已过了保修期&#xff0c;您将无法享受制造商的免费保修服务。 这意味着您必须自费找到一家电脑维修店。 去电脑维修店并不容易。 大家一定要知道&#xff0c;电脑维修非常困难&#xff0c;尤其是笔记本电脑维…

美国站群服务器租用需要考虑哪些关键点

美国站群服务器租用通常指的是租用位于美国数据中心的服务器&#xff0c;这些服务器具备多个IP地址&#xff0c;适合用于建立和管理多个网站(即站群)。那么美国站群服务器租用需要考虑哪些关键点&#xff0c;RAKsmart小编为您整理发布美国站群服务器租用需要考虑哪些关键点。 在…

基于rk3568解决gpio阶梯波形(适用于i2c、uart、电平转换)

目录 1、理解GPIO的开漏&#xff08;OD&#xff09;和开集&#xff08;OC&#xff09; 2、查询io寄存器地址及定义 3、配置可调寄存器接口dev/mem author daisy.skye的博客_CSDN博客-嵌入式,Qt,Linux领域博主 daisy.skye_嵌入式,Linux,Qt-CSDN博客daisy.skye擅长嵌入式,Linux,Q…

gorm快速上手

简介 1.什么是orm ORM全称是:Object Relational Mapping(对象关系映射)&#xff0c;其主要作用是在编程中&#xff0c;把面向对象的概念跟数据库中表的概念对应起来。举例来说就是&#xff0c;我定义一个对象&#xff0c;那就对应着一张表&#xff0c;这个对象的实例&#xf…

广播

1.什么是广播 2.标准广播 BroadStandardActivity.java package com.tiger.chapter09;import androidx.appcompat.app.AppCompatActivity;import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.view.View;…

1688商品采集API轻松实现商品上传上货搬家

item_get-获得1688商品详情 公共参数 请求地址: 1688/item_get 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&#xff09;[item_search,item_get,…

安卓 Kotlin 面试题 21-30

&#x1f525; 21、 Kotlin 中的“open”和“public”有什么区别&#xff1f;&#x1f525; open 关键字的意思是“为扩展而开放” 。 类上的 open 注释与 Java 的相反 final&#xff1a;它允许其他人从该类继承。 如果您不指定任何可见性修饰符&#xff0c;则默认使用public&…

Qt 范例阅读 :插件功能 plugabdpaint

一、源码目录&#xff1a; Qt\Examples\Qt-5.12.4\widgets\tools\plugandpaint 二、定义接口 class FilterInterface { public:virtual ~FilterInterface() {}virtual QStringList filters() const 0;virtual QImage filterImage(const QString &filter, const QImage &…

vscode 使用ssh进行远程开发 (remote-ssh),首次连接及后续使用,详细介绍

在vscode添加remote ssh插件 首次连接 选择左侧栏的扩展&#xff0c;并搜索remote ssh 它大概长这样&#xff0c;点击安装 安装成功后&#xff0c;在左侧栏会出现远程连接的图标&#xff0c;点击后选择ssh旁加号便可以进行连接。 安装成功后vscode左下角会有一个图标 点击图…

Java核心技术卷1每日笔记——变量与常量

3.4 变量与常量 与所有程序设计语言一样&#xff0c;Java也使用变量来存储值。常量就是值不变的量。 3.4.1 声明变量 在Java中&#xff0c;每个变量都有一个类型&#xff08;type&#xff09;。 变量名必须是一个以字母开头并由字母或数字构成的序列。 字母包括’A’‘Z’、…

网页在特殊日子一键变灰

<template> <div :class"{ grayscale: isGrayscale }"> <!-- 你的页面内容放在这里 --> </div> </template> <script> export default { data() { return { // 存储哀悼日的数组 aidaoriDates:["0404", &q…

docker学习入门

1、docker简介 docker官网&#xff1a; www.docker.com dockerhub官网&#xff1a; hub.docker.com docker文档官网&#xff1a;docs.docker.com Docker是基于Go语言实现的云开源项目。 Docker的主要目标是&#xff1a;Build, Ship and Run Any App, Anywhere(构建&…

1.2_2 OSI参考模型

文章目录 1.2_2 OSI参考模型一、概述&#xff08;一&#xff09;ISO/OSI参考模型是怎么来的&#xff1f;&#xff08;二&#xff09;ISO/OSI参考模型&#xff08;三&#xff09;ISO/OSI参考模型解释通信过程 二、各层功能及协议&#xff08;一&#xff09;应用层&#xff08;第…

oss-fuzz-gen:一款基于LLM的模糊测试对象生成与评估框架

关于oss-fuzz-gen oss-fuzz-gen是一款基于LLM的模糊测试对象生成与评估框架&#xff0c;该工具可以帮助广大研究人员使用多种大语言模型&#xff08;LLM&#xff09;生成真实场景中的C/C项目以执行模糊测试。 该工具基于Google的OSS-Fuzz平台实现其功能&#xff0c;并对生成的…