⭐前言⭐
※※※大家好!我是同学〖森〗,一名计算机爱好者,今天让我们进入学习模式。若有错误,请多多指教。更多有趣的代码请移步Gitee
👍 点赞 ⭐ 收藏 📝留言 都是我创作的最大的动力!
1. 思维导图
2. 获取邮箱授权码
2.1 1. 开启POP3/SMTP服务
- 登录QQ邮箱 --> 设置 --> 账户
- 向下滑动滚动条,找到账户页面下方的 POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务一栏,点击管理服务
- 第一次会让你绑定手机后再进行操作 按要求进行操作就好;
- 进入安全模式,点击生成授权码;
- 短信验证
- 验证成功会生成授权码
一定要复制授权码,并保存到一个地方;别问我怎么知道的;
3. 创建 Spring Boot 项目
3.1 引入依赖
<!-- 发送邮件 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
添加依赖后一定要重新 ReLoad 一下;
3.2 配置application.yml文件
Spring:
# 邮箱基本配置
mail:
# 配置 smtp 服务主机地址
# qq 邮箱 smtp.qq.com 端口号 465 或 587
# sina smtp.sina.com
# aliyun smtp.aliyun.com
# 163 smtp.163.com 端口号 465 或 994
host: smtp.qq.com
# 发送者邮箱
username: xxxxxxxx@qq.com
# 在邮箱内申请的授权码
password: xttfwlhoyguxbacg
# 端口号
port: 587
# 默认的邮件编码为UTF-8
default-encoding: UTF-8
# 其他参数
properties:
mail:
# 配置SSL 加密工厂
smtp:
ssl:
# 本地测试, 先放开ssl
enable: false
required: false
#开启debug模式,这样邮件发送过程的日志会在控制台打印出来,方便排查错误
debug: true
- 这里注意一下port 465有时会报错,换一个就好;
- 把username 改成自己的QQ邮箱号,把password 换成刚刚我们申请的授权码(不是QQ密码哟)
3.3 实体类ToEmail
package com.example.sendemail.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import java.io.Serializable;
/**
* @version IntelliJ IDEA || java version 11.
* @Author: Oliver
* @Description: 邮箱验证码实体类
* @Date: 2023-07-02
* @Time: 14:21
*/
@Data
@AllArgsConstructor //生成一个包含所有类字段的构造函数
public class ToEmail implements Serializable {
/**
* 邮件接受方
*/
private String tos;
/**
* 邮件主题
*/
private String subject;
/**
* 邮件内容
*/
private String content;
}
3.4 生成6位验证码
package com.example.sendemail.utils;
import java.security.SecureRandom;
import java.util.Random;
/**
* @version IntelliJ IDEA || java version 11.
* @Author: Oliver
* @Description: 生成验证码工具类
* @Date: 2023-07-02
* @Time: 14:35
*/
public class VerCodeGenerateUtil {
/**
* 验证码包含的字段
*/
private static final String SYMBOLS = "0123456789ABCDEFGHIGKLMNOPQRSTUVWXYZ";
private static final Random RAND = new SecureRandom();
/**
* 生成 6 位数的随机数字
* @return {@link String 验证码}
*/
public static String generateVerCode(){
char[] code = new char[6];
for(int i = 0; i < code.length; i++) {
code[i] = SYMBOLS.charAt(RAND.nextInt(SYMBOLS.length()));
// RAND.nextInt(SYMBOLS.length()) 生成一个随机的索引值;
// RAND.nextInt(n) 生成一个0到n-1之间的随机整数;
}
return new String(code);
}
}
SecureRandom() 和 Random()
java.util.Random
是一个伪随机数生成器,它使用线性同余算法生成随机数。
- 这种算法虽然能够快速生成随机数,但是它的随机性并不够强,因此不适用于安全相关的场景。在Java中,使用java.util.Random生成的随机数只能用于一些非安全性的场景,例如模拟数据或游戏等。
java.security.SecureRandom
是一个强随机数生成器,它使用安全的随机数生成算法生成随机数。
- 这种算法的随机性更加强大和安全,可以用于安全相关的场景,例如密码学或安全通信等。在Java中,使用
java.security.SecureRandom
生成的随机数可以用于安全性要求更高的场景。
3.5 邮件服务器类MailService
package com.example.sendemail.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.javamail.JavaMailSenderImpl;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.apache.commons.lang3.StringUtils;
import javax.annotation.Resource;
import javax.mail.MessagingException;
import java.io.File;
import java.util.Date;
@Service
public class MailService {
/**
* 注入邮件工具类
*/
@Resource
private JavaMailSenderImpl javaMailSender;
@Value("${spring.mail.username}")
private String sendMailer;
/**
* 检测邮件信息类
* @param receiveEmail 接收者
* @param subject 主题
* @param emailMsg 内容
*/
private void checkMail(String receiveEmail, String subject, String emailMsg){
// StringUtils 需要引入 commons-lang3 依赖
// 可以用 receiveEmail == null || receiveEmail.isEmpty() 来代替
if(StringUtils.isEmpty(receiveEmail)) {
throw new RuntimeException("邮件收件人不能为空");
}
if(StringUtils.isEmpty(subject)) {
throw new RuntimeException("邮件主题不能为空");
}
if(StringUtils.isEmpty(emailMsg)) {
throw new RuntimeException("邮件内容不能为空");
}
}
/**
* 发送纯文本邮件
* @param receiveEmail 接收者
* @param subject 主题
* @param emailMsg 内容
*/
public Boolean sendTextMail(String receiveEmail, String subject, String emailMsg) {
// 参数检查
checkMail(receiveEmail, subject, emailMsg);
try {
// true 代表支持复杂的类型
MimeMessageHelper mimeMessageHelper = new MimeMessageHelper(javaMailSender.createMimeMessage(), true);
// 邮件发件人
mimeMessageHelper.setFrom(sendMailer);
// 邮件收件人
mimeMessageHelper.setTo(receiveEmail.split(","));
// 邮件主题
mimeMessageHelper.setSubject(subject);
// 邮件内容
mimeMessageHelper.setText(emailMsg);
// 邮件发送时间
mimeMessageHelper.setSentDate(new Date());
// 发送邮件
javaMailSender.send(mimeMessageHelper.getMimeMessage());
System.out.println("发送邮件成功: " + sendMailer + "-->" + receiveEmail);
return true;
} catch (MessagingException e) {
e.printStackTrace();
System.out.println("发送邮件失败: " + e.getMessage());
return false;
}
}
}
3.6 EmailController
package com.example.sendemail.controller;
import com.example.sendemail.common.AjaxResult;
import com.example.sendemail.entity.ToEmail;
import com.example.sendemail.service.MailService;
import com.example.sendemail.utils.VerCodeGenerateUtil;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
/**
* @version IntelliJ IDEA || java version 11.
* @Author: Oliver
* @Description: 邮箱验证码
* @Date: 2023-07-02
* @Time: 15:06
*/
@RestController
@RequestMapping("/email")
public class EmailController {
@Resource
private MailService mailService;
@RequestMapping("/sendEmail")
public AjaxResult sendEmail(ToEmail toEmail, HttpServletRequest request) {
if(toEmail == null || toEmail.getTos() == null ) {
return AjaxResult.fail(-1, "参数错误!");
}
toEmail.setSubject("你本次的验证码是");
// 获取验证码
String verCode = VerCodeGenerateUtil.generateVerCode();
String content = "尊敬的xxx,您好:\n"
+ "\n本次请求的邮件验证码为:" + verCode + ",本验证码 5 分钟内效,请及时输入。(请勿泄露此验证码)\n"
+ "\n如非本人操作,请忽略该邮件。\n(这是一封通过自动发送的邮件,请不要直接回复)";
toEmail.setContent(content);
Boolean check = mailService.sendTextMail(toEmail.getTos(), toEmail.getSubject(), toEmail.getContent());
if(check) {
return AjaxResult.success(200, "发送成功");
} else {
return AjaxResult.fail(-2, "发送失败");
}
}
}
- AjaxResult 统一格式返回类,包含 状态码 code , 状态码描述信息 msg, 返回的数据 data;
4 功能测试
使用 PostMan测试
其中 tos 的 val 值是要收件人的邮箱;