引包
<!--引入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";
}
}
}
}
测试
输入邮箱后,点击“免费获取验证码”按钮,点击后的效果图如下,此时输入的邮箱应该已经收到验证码了
输入昵称,密码,验证码
点击提交,跳转到了指定页面,如下图