0. 步骤
- 开启邮箱的 POP3/SMTP 服务。
- 新建 springboot 项目。
- 导入依赖。
- 配置配置文件。
- 编写 controller 测试接口。
- ApiPost中测试
- 新建html网页测试
1. 开启邮箱的 POP3/SMTP 服务
本次使用QQ邮箱,其他邮箱开启方式相同:

打开后生成授权码,会获得一个授权码,这个授权码很重要,后面会用到,生成后需要立刻保存,后面无法再次查询到

2. 新建 springboot 项目
x项目结构:

使用application.yml和 application.properties 的区别体现在使用时yml的层级结构会更加的清晰
3. 导入依赖
这里我导入两个依赖,分别是 spring-boot-starter-mail 和 hutool-all
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-mail</artifactId> </dependency>
<dependency> <groupId>cn.hutool</groupId> <artifactId>hutool-all</artifactId> <version>5.8.19</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
|
4. 配置配置文件
这里使用层级更加清晰的yml结构:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| server: port: 8080
spring: mail: host: smtp.qq.com protocol: smtp default-encoding: UTF-8 username: *****@qq.com password: *****
nickname: 康弟弟
test-connection: true properties: mail: smtp: auth: true starttls: enable: true required: true
|
5. controller 和 测试接口
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
| package com.kd_13.emailcode;
import cn.hutool.core.util.RandomUtil; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.mail.SimpleMailMessage; import org.springframework.mail.javamail.JavaMailSender; import org.springframework.web.bind.annotation.*;
import java.util.HashMap; import java.util.Map;
@RestController @RequestMapping("/email") public class EmailController {
@Autowired private JavaMailSender mailSender;
@Value("${spring.mail.username}") private String sender;
@Value("${spring.mail.nickname}") private String nickname;
private Map<String, CodeEntry> codeMap = new HashMap<>();
@GetMapping("/code") public String getCode(@RequestParam("email") String email) { SimpleMailMessage message = new SimpleMailMessage(); message.setFrom(nickname + '<' + sender + '>'); message.setTo(email); message.setSubject("欢迎访问康弟弟的网站");
String code = RandomUtil.randomNumbers(6); System.out.println("code"+code); String content = "【验证码】您的验证码为:" + code + " 。 验证码五分钟内有效,逾期作废。" +"------------------------------\n\n\n" + "更多博客可访问:\n\n" + "https://kd-13.cn/\n\n";;
message.setText(content);
mailSender.send(message);
codeMap.put(email, new CodeEntry(code, System.currentTimeMillis() + 5 * 60 * 1000));
return "发送成功!"; }
@PostMapping("/checkcode") public String checkCode(@RequestParam("email") String email, @RequestParam("code") String code) { CodeEntry entry = codeMap.get(email); if (entry == null || !entry.getCode().equals(code)) {
return "验证码错误或已过期!"; } if (System.currentTimeMillis() > entry.getExpiryTime()) { codeMap.remove(email); return "验证码已过期!"; } codeMap.remove(email); return "验证成功!"; }
private static class CodeEntry { private String code; private long expiryTime;
public CodeEntry(String code, long expiryTime) { this.code = code; this.expiryTime = expiryTime; }
public String getCode() { return code; }
public long getExpiryTime() { return expiryTime; } } }
|
6. 接口测试
使用ApiPost进行测试,测试端口如下:
1
| http://localhost:8080/email/code?email=****@qq.com
|

1
| http://localhost:8080/email/checkcode?email =****@qq.com&code =****
|

7. 网页测试
搭建一个简易的html页面对接口进行测试,还是放在同一个端口的应用下测试解决跨域问题,其中的jquery可以使用网络加载映入,但是网络慢的话网站的打开也会很慢,所以我这里直接下载下来了。
1
| https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>邮箱验证码示例</title> <script src="jquery.min.js"></script> <script> function startTimer(duration, display) { var timer = duration, minutes, seconds; var interval = setInterval(function () { minutes = parseInt(timer / 60, 10); seconds = parseInt(timer % 60, 10);
minutes = minutes < 10 ? "0" + minutes : minutes; seconds = seconds < 10 ? "0" + seconds : seconds;
display.text(seconds);
if (--timer < 0) { clearInterval(interval); display.text('发送验证码'); display.prop('disabled', false); } }, 1000); }
function sendCode() { var email = $('#email').val(); var sendButton = $('#sendButton'); sendButton.prop('disabled', true); sendButton.text('发送中...');
$.ajax({ url: '/email/code', type: 'GET', data: { email: email }, success: function(response) { if (response === "发送成功!") { alert("发送成功!") sendButton.text('60'); startTimer(60, sendButton); } else { sendButton.prop('disabled', false); sendButton.text('发送验证码'); } }, error: function(error) { alert('发送验证码失败,请稍后再试。'); sendButton.prop('disabled', false); sendButton.text('发送验证码'); } }); }
function checkCode() { var email = $('#email').val(); var code = $('#code').val(); $.ajax({ url: '/email/checkcode', type: 'POST', data: { email: email, code: code }, success: function(response) { alert(response); }, error: function(error) { alert('核对验证码失败,请稍后再试。'); } }); } </script> </head> <body>
<h2>邮箱验证码示例</h2>
<label for="email">邮箱地址:</label> <input type="email" id="email" name="email" required> <button id="sendButton" onclick="sendCode()">发送验证码</button>
<br><br>
<label for="code">验证码:</label> <input type="text" id="code" name="code" required> <button onclick="checkCode()">核对验证码</button>
</body> </html>
|


8. 改进
可以将数据存储到Redis 中