admin管理员组文章数量:1634854
目录
1、使用Springboot发送模板邮件并测试
1、添加依赖
2、配置application.properties
3、编写HTML邮件模板
4、编写发送邮件工具类
5、测试
2、在用户使用邮箱注册业务中----使用多线程异步发送账户激活邮件
1、配置线程池
2、在邮件工具类发送邮件的方法上添加@Async注解
3、实现邮箱注册功能
3.1 点击注册,将邮箱和密码发送给后端
3.2、后端处理请求,将结果封装到AjaxResult中返回
4、实现邮箱激活功能
4.1、点击邮件里的激活链接,跳转到激活页面
4.2、后端激活用户接口,操作数据库修改state为1
3、邮箱注册激活完整流程
1、进入注册页面,点击注册
2、进入邮箱,查看邮件
3、点击邮件中的链接去完成用户激活
4、激活成功,跳转到登录界面:
1、使用Springboot发送模板邮件并测试
1、添加依赖
<!--mail-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!--thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
2、配置application.properties
需要获取邮箱授权码,这里我就不详细讲了
# 设置邮箱主机(服务商)
spring.mail.host=smtp.qq
# 设置用户名
spring.mail.username=xxx@qq
# 设置密码,该处的密码是QQ邮箱开启SMTP的授权码而非QQ密码
spring.mail.password=xxx
# 设置编码
spring.mail.default-encoding=UTF-8
#发件人
# 必须进行授权认证,它的目的就是阻止他人任意乱发邮件
spring.mail.properties.mail.smtp.auth=true
#SMTP加密方式:连接到一个TLS保护连接
spring.mail.properties.mail.smtp.starttls.enable=true
spring.mail.properties.mail.smtp.starttls.required=true
# JavaMailSender 配置
spring.mail.port=465
#SSL 配置
spring.mail.protocol=smtp
spring.mail.properties.mail.smtp.ssl.enable=true
spring.mail.properties.mail.smtp.socketFactory.port=465
spring.mail.properties.mail.smtp.socketFactory.class=javax.ssl.SSLSocketFactory
3、编写HTML邮件模板
将该模板页面放在resources下的templates目录下:registerTemplate.html
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf">
<head>
<meta charset="UTF-8">
<title>激活邮件</title>
<style type="text/css">
* {
margin: 0;
padding: 0;
box-sizing: border-box;
font-family: Arial, Helvetica, sans-serif;
}
body {
background-color: #ECECEC;
}
.container {
width: 800px;
margin: 50px auto;
}
.header {
height: 80px;
background-color: #49bcff;
border-top-left-radius: 5px;
border-top-right-radius: 5px;
padding-left: 30px;
}
.header h2 {
padding-top: 25px;
color: white;
}
.content {
background-color: #fff;
padding-left: 30px;
padding-bottom: 30px;
border-bottom: 1px solid #ccc;
}
.content h2 {
padding-top: 20px;
padding-bottom: 20px;
}
.content p {
padding-top: 10px;
}
.footer {
background-color: #fff;
border-bottom-left-radius: 5px;
border-bottom-right-radius: 5px;
padding: 35px;
}
.footer p {
color: #747474;
padding-top: 10px;
}
</style>
</head>
<body>
<div class="container">
<div class="header">
<h1>欢迎加入宠物之家!</h1>
</div>
<div class="content">
<h2>亲爱的用户,您好!</h2>
<p>您的邮箱:<b><span th:text="${email}"></span></b></p>
<p>您的激活码:<b><span th:text="${code}"></span></b></p>
<p>您注册时的日期:<b><span th:text="${createTime}"></span></b></p>
<P><b>请在10分钟内完成激活:<a href="http://127.0.0.1:8083/activation.html">点我激活</a></b></P>
<p></p>
<p>当您在使用本网站时,务必要遵守法律法规</p>
<p>如果您有什么疑问可以联系管理员,Email: <b>r1624603357@126</b></p>
</div>
<div class="footer">
<p>此为系统邮件,请勿回复</p>
<p>请保管好您的信息,避免被他人盗用</p>
<p>©Rk</p>
</div>
</div>
</body>
</html>
4、编写发送邮件工具类
package com.rk.pethome.basic.util;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;
import javax.mail.internet.MimeMessage;
import java.util.Map;
@Component
public class SendMailUtil {
//发件人
private String sender="1624603357@qq";
@Autowired
JavaMailSender javaMailSender;
@Autowired
TemplateEngine templateEngine;
/**
* 发送邮件
* @param receiver 收件人
* @param subject 邮件标题
* @param emailTemplate HTML模板
* @param dataMap 模板中的数据
* @throws Exception
*/
@Async//异步发送注解
public void sendTemplateMail(String receiver, String subject, String emailTemplate, Map<String, Object> dataMap) throws Exception {
//给模板引擎提供变量
Context context = new Context();
//设置传入模板页面的值 从dataMap中获取
for (Map.Entry<String, Object> entry : dataMap.entrySet()) {
context.setVariable(entry.getKey(), entry.getValue());//例如:context.setVariable("code",123)
}
//emailTemplate是你要发送的模板,我这里用的是Thymeleaf emailTemplate="registerTemplate"
String templateContent = templateEngine.process(emailTemplate, context);
//准备发送邮件
MimeMessage message = javaMailSender.createMimeMessage();
MimeMessageHelper helper = new MimeMessageHelper(message, true);
//设置发件人
helper.setFrom(sender);
//设置收件人
helper.setTo(receiver);
//设置标题
helper.setSubject(subject);
//设置内容
helper.setText(templateContent, true);
javaMailSender.send(message);
}
}
5、测试
package com.rk.pethome.mail;
import com.rk.pethome.basic.util.SendMailUtil;
import com.rk.pethome.basic.util.StrUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.mail.internet.MimeMessage;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
@SpringBootTest
@RunWith(SpringJUnit4ClassRunner.class)
public class MailSenderTest {
@Autowired
private SendMailUtil mailUtil;
//收件人
private final String receiver = "1624603357@qq";
@Test
public void testTemplateMail(){
//发送邮件
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
String subject = "宠物之家--用户注册";
String emailTemplate = "registerTemplate";
String code = StrUtils.getRandomString(5);
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("email", receiver);
dataMap.put("code", code);
dataMap.put("createTime", sdf.format(new Date()));
try {
mailUtil.sendTemplateMail(receiver, subject, emailTemplate, dataMap);
System.out.println("发送完成");
} catch (Exception e) {
e.printStackTrace();
return;
}
}
}
2、在用户使用邮箱注册业务中----使用多线程异步发送账户激活邮件
1、配置线程池
package com.rk.pethome.basic.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import java.util.concurrent.Executor;
@Configuration
@EnableAsync // 启用异步任务
public class AsyncConfiguration {
// 声明一个线程池(并指定线程池的名字)
@Bean("taskExecutor")
public Executor asyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
//核心线程数5:线程池创建时候初始化的线程数
executor.setCorePoolSize(5);
//最大线程数5:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
executor.setMaxPoolSize(5);
//缓冲队列500:用来缓冲执行任务的队列
executor.setQueueCapacity(500);
//允许线程的空闲时间60秒:当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
executor.setKeepAliveSeconds(60);
//线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
executor.setThreadNamePrefix("DailyAsync-");
executor.initialize();
return executor;
}
}
2、在邮件工具类发送邮件的方法上添加@Async注解
3、实现邮箱注册功能
3.1 点击注册,将邮箱和密码发送给后端
//通过邮箱注册用户
emilReg(){
//获取参数
let para = Object.assign({}, this.user);
//发送请求
this.$http.post("/user/registerByEmial",para).then((res)=>{
console.debug(res);
console.debug(para);
let {success,msg}=res.data;
if(!success)//如果失败
{
this.errorMsg=msg;
}else{
//清空错误信息
this.errorMsg="";
//location.href="login.html";
}
});
},
3.2、后端处理请求,将结果封装到AjaxResult中返回
AjaxResult:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class AjaxResult {
private Boolean success=true;
private String msg;
//返回到前端的结果值
private Object result;
public AjaxResult(Boolean success,String msg)
{
this.success=success;
this.msg=msg;
}
public AjaxResult setResult(Object result){
this.result=result;
return this;
}
}
Controller层:
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private IUserService userService;
/**
* 通过邮箱进行注册
* @param userDot
* @return
*/
@PostMapping("/registerByEmial")
public AjaxResult registerByEmial(@RequestBody UserDot userDot){
try {
System.out.println(userDot);
return userService.registerEmail(userDot);
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult(false,"注册失败");
}
}
}
Service层:
1、首先判断密码是否输入并且两次密码输入是否一致,在此之前已经进行异步的判断其是否已经注册,所以这里就不用判断邮箱。
2、将注册的邮箱和密码保存到数据库中,邮箱同时也是用户名
3、异步(多线程)的发送激活邮件,如果不是异步,发送邮件大概需要6s左右,极大降低用户的使用体验,点击注册后之间卡了6s---还以为是网络出现问题
注意:发送邮件的方法上也要使用 @Async注解 这样才能异步执行
4、发送模板邮件的testTemplateMail方法中,会生成激活码,将该激活码存储在redis服务器上
@Service
public class IUserServiceImpl extends BaseServiceImpl<User> implements IUserService {
@Autowired
private UserMapper userMapper;
@Autowired
private SendMailUtil mailUtil;
/**
* 通过邮箱进行注册
* @param userDot
* @return
*/
@Override
public AjaxResult registerEmail(UserDot userDot){
try {
//判断密码是否输入
if(StringUtils.isBlank(userDot.getPassword())||StringUtils.isBlank(userDot.getConfirmPassword()))
return new AjaxResult(false,"请输入密码");
//如果两次面不相等
if(!userDot.getPassword().equals(userDot.getConfirmPassword()))
return new AjaxResult(false,"两次密码不一致");
//保存对象
User user=new User();
user.setUsername(userDot.getEmail());
user.setEmail(userDot.getEmail());
user.setCreatetime(new Date());
user.setState(0);//手机验证通过后已激活
//给用户密码进行盐值加密
user.setPassword(MD5Utils.encrypByMd5(userDot.getPassword()));
//保存用户
userMapper.saveUser(user);
//给刚注册好的用户发送邮件
testTemplateMail(user.getEmail());
return new AjaxResult(false,"邮件已发送至邮箱,请在10分钟内完成激活!");
} catch (Exception e){
e.printStackTrace();
return new AjaxResult(false,"注册失败!");
}
}
/**
* 发送邮件
* @param receiver 收件人
*/
@Async
public void testTemplateMail(String receiver){
//发送邮件
SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒");
String subject = "宠物之家--用户注册";
String emailTemplate = "registerTemplate";
//获取激活码
String code = StrUtils.getRandomString(5);
//将激活码存入redis服务器
//设置有效期10分钟 key值为:Action+邮箱 value值为:验证码
RedisUtils.INSTANCE.set("Action:"+receiver,code,10*60);
System.out.println("key:"+"Action:"+receiver+" value:"+code);
Map<String, Object> dataMap = new HashMap<>();
dataMap.put("email", receiver);
dataMap.put("code", code);
dataMap.put("createTime", sdf.format(new Date()));
try {
mailUtil.sendTemplateMail(receiver, subject, emailTemplate, dataMap);
System.out.println("发送完成");
} catch (Exception e) {
e.printStackTrace();
return;
}
}
}
Mapper层:
/**
* 保存用户
* @param user
*/
void saveUser(User user);
Mapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis//DTD Mapper 3.0//EN"
"http://mybatis/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.rk.pethome.user.mapper.UserMapper">
<!--保存用户-->
<insert id="saveUser" parameterType="user">
insert into t_user(username,email,phone, password, state, createtime)
VALUES (#{username},#{email},#{phone},#{password},#{state},#{createtime})
</insert>
</mapper>
此时用户state属性为0,用户是未激活的状态 我们需要去邮箱点击激活按钮后完成激活操作才能登陆。
4、实现邮箱激活功能
4.1、点击邮件里的激活链接,跳转到激活页面
userActivation(){
let para={"email":this.email,"code":this.code};
this.$http.post("/user/userAction",para).then((res)=> {
let {success,msg}=res.data;
if(!success)//如果激活 //打印失败信息
{
this.errorMsg=msg;
}else{
//清空错误信息
this.errorMsg="";
//完成激活,跳转到登录页面
location.href="login.html";
}
})
},
4.2、后端激活用户接口,操作数据库修改state为1
Controller层:
/**
* 通过邮箱或者手机号登陆
* @return
*/
@PostMapping("/userAction")
public AjaxResult activation(@RequestBody HashMap<String,String> para){
try {
System.out.println(para.get("code"));
String email=para.get("email");
String code = para.get("code");
return userService.activation(email,code);
} catch (Exception e) {
e.printStackTrace();
return new AjaxResult(false, e.getMessage());
}
}
Service层:
1、判断输入的值是否为空
2、接收传递过来的email,通过Action+email来过去该用户的激活码,code为用户输入的激活码。
3、通过Action+email从redis服务器上能否获取值来判断:用户名是否输入正确或者激活码是否过期。如果不为空与用户输入的值进行对比。相等则说明激活码正确。
4、通过email修改用户的state为1。表示该用户已激活,此时移除redis服务器上的激活码
/**
* 用户激活
*
* @param email 邮箱
* @param code 激活码
* @return
*/
@Override
public AjaxResult activation(String email, String code) {
//判断输入是否为空
if(StringUtils.isBlank(email)||StringUtils.isBlank(code)){
return new AjaxResult(false,"请输入邮箱和激活码!!");
}
//校验激活码是否正常
//从redis服务器中获取code值,如果code值为空,说明激活码错误或者已过期!
String s = RedisUtils.INSTANCE.get("Action:" + email);//redis服务器上获取的激活码
System.out.println("redis服务器上获取的激活码为:"+s);
if(s==null)
return new AjaxResult(false,"邮箱错误或者激活码已过期!!");
//激活码是否正确
if(!code.equals(s))//不正确
{
return new AjaxResult(false,"激活码错误!!");
}
//激活后从redis服务器上移除
RedisUtils.INSTANCE.del("Action:" + email);
//修改用户状态为1 说明用户已经激活
userMapper.updateState(email);
return new AjaxResult();
}
Mapper层:
/**
* 激活用户
* @param email
*/
void updateState(String email);
Mapper.xml:
<!--修改用户为激活状态-->
<update id="updateState">
update t_user set state=1 where email=#{email}
</update>
3、邮箱注册激活完整流程
1、进入注册页面,点击注册
2、进入邮箱,查看邮件
查看redis服务器上的key :
查看数据库中注册的用户:
3、点击邮件中的链接去完成用户激活
输入错误的激活码:
输入正确的激活码:
4、激活成功,跳转到登录界面:
查看数据库中的用户
查看redis服务器上的激活码:
本文标签: 模板邮件功能SpringBoot
版权声明:本文标题:使用Springboot异步发送模板邮件完成注册功能 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1729202275a1189764.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论