Spring中的aware接口详情
752
2022-09-08
SpringBoot发送html邮箱验证码功能
1. 效果展示(用户收到的)
2. 邮件推送管理(见以后的博客)
先看看如果管理员手动发送该如何操作
3. 后端核心代码(通用版)
3.1 SendEmailVO实体类
package com.example.han.model.VO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Map;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Schema(description = "发送邮件VO实体类")
public class SendEmailVO {
@Schema(description = "收件人邮箱")
String toAddress;
@Schema(description = "模板名")
String modelName;
@Schema(description = "邮件标题")
String title;
@Schema(description = "文本里所需要参数")
Map
@Schema(description = "调用者类型(管理员/服务)")
String manageType;
@Schema(description = "(调用者/服务)名称")
String manager;
}
3.2 Controller层核心代码
@Operation(summary = "发送html邮件")
@PutMapping("/sendemail")
public ResultReturn sendEmail(@RequestBody SendEmailVO sendEmailVO){
return (sendModelService.sendEmailByParam(sendEmailVO));
}
3.3 ServiceImpl层核心代码
@Autowired
HtmlEmailServiceImpl htmlEmailService;
/**
* 通过模板名查找html文本
* @param name 模板名
* @return 返回html文本
*/
public String getTextByName(String name){
List
for (MailModelDO list : lists){
if(list.getModelName().equals(name)){
return list.getHtmlText();
}
}
return "NOT FOUND";
}
/**
* 发送邮件的操作
* @param sendEmailVO 发送邮件VO实体类
* @return 收件人邮箱
*/
public ResultReturn sendEmailByParam(SendEmailVO sendEmailVO){
String str = getTextByName(sendEmailVO.getModelName());
if(!CheckMail.checkMail(sendEmailVO.getToAddress())){
return ResultReturnUtil.fail(WRONG_EMAIL_ADDRESS);
}
if(sendEmailVO.getTitle().equals("")){
return ResultReturnUtil.fail(EMPTY_TITLE);
}
if(str.equals("NOT FOUND")){
return ResultReturnUtil.fail(FIND_MODEL_FAILED);
}
ReplaceWordUtil replaceWordUtil = new ReplaceWordUtil();
String content = replaceWordUtil.replaceWord(str,sendEmailVO.getParameters());
MailInfoTO info = new MailInfoTO();
info.setToAddress(sendEmailVO.getToAddress());
info.setSubject(sendEmailVO.getTitle());
info.setContent(content);
try {
htmlEmailService.sendHtmlMail(info);
} catch (Exception e) {
//System.out.print("'"+sendEmailVO.getTitle()+"'的邮件发送失败!");
e.printStackTrace();
}
MailHistoryDO mailHistoryDO = ToBeMailHistoryDO(sendEmailVO);
mailRepository.saveHistory(mailHistoryDO);
return ResultReturnUtil.success(SEND_EMAIL_SUCCESS,sendEmailVO.getToAddress());
}
3.4 利用正则检查邮箱是否合法工具类
package com.example.han.util;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class CheckMail {
public static boolean checkMail(String mail){
Pattern pattern=Pattern.compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
//\w+@(\w+.)+[a-z]{2,3}
Matcher matcher=pattern.matcher(mail);
return matcher.matches();
}
}
3.5 字符替换工具类
就是为了将模板中的花括号替换成真正需要的东西
package com.example.han.util;
import java.util.Iterator;
import java.util.Map;
/**
* 将str通过map的key转换成value
*/
public class ReplaceWordUtil {
public String replaceWord(String str, Map
Iterator iter = http://map.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Map.Entry) iter.next();
Object key = entry.getKey();
Object value = entry.getValue();
str = str.replace("{{"+key+"}}",value+"");
//System.out.println(key+":"+value);
}
//System.out.println(str);
return str;
}
}
3.6 Reposity层 逻辑并不是很好,是找出来所有模版以后,开始遍历出来想要的那一个
package com.example.han.repository;
import com.example.han.model.DO.MailHistoryDO;
import com.example.han.model.DO.MailModelDO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public class MailRepository {
@Autowired
MongoTemplate mongoTemplate;
public List
System.out.println(mongoTemplate.findAll(MailModelDO.class));
return mongoTemplate.findAll(MailModelDO.class);
}
}
3.7 发送html邮件的核心配置类
package com.example.han.service.impl;
import com.example.han.model.TO.MailInfoTO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import javax.mail.*;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import java.util.Date;
import java.util.Properties;
@Service
public class HtmlEmailServiceImpl{
@Value("${spring.mail.host}")
private String host;
@Value("${spring.mail.username}")
private String formName;
@Value("${spring.mail.password}")
private String password;
@Value("${spring.mail.username}")
private String replayAddress;
/**
* 发送html邮件
* @param info MailInfo实体类
* @throws Exception 抛出异常
*/
public void sendHtmlMail(MailInfoTO info) throws Exception {
System.out.println(host);
System.out.println(formName);
info.setHost(host);
info.setFormName(formName);
info.setFormPassword(password); //网易邮箱的授权码~不一定是密码
info.setReplayAddress(replayAddress);
System.out.println(info.getHost());
System.out.println(info.getContent());
Message message = getMessage(info);
// MiniMultipart类是一个容器类,包含MimeBodyPart类型的对象
Multipart mainPart = new MimeMultipart();
// 创建一个包含HTML内容的MimeBodyPart
BodyPart html = new MimeBodyPart();
// 设置HTML内容
html.setContent(info.getContent(), "text/html; charset=utf-8");
mainPart.addBodyPart(html);
// 将MiniMultipart对象设置为邮件内容
message.setContent(mainPart);
Transport.send(message);
}
public Message getMessage(MailInfoTO info) throws Exception{
final Properties p = System.getProperties() ;
p.setProperty("mail.smtp.host", info.getHost());
p.setProperty("mail.smtp.auth", "true");
p.setProperty("mail.smtp.user", info.getFormName());
p.setProperty("mail.smtp.pass", info.getFormPassword());
// 根据邮件会话属性和密码验证器构造一个发送邮件的sessiqceXeEon
Session session = Session.getInstance(p, new Authenticator(){
protected PasswordAuthentication getPasswordAuthentication() {
return new PasswordAuthentication(p.getProperty("mail.smtp.user"),p.getProperty("mail.smtp.pass"));
}
});
session.setDebug(true);
Message message = new MimeMessage(session);
//消息发送的主题
message.setSubject(info.getSubject());
//接受消息的人
message.setReplyTo(InternetAddress.parse(info.getReplayAddress()));
//消息的发送者
message.setFrom(new InternetAddress(p.getProperty("mail.smtp.user"),"这是我的名字"));
// 创建邮件的接收者地址,并设置到邮件消息中
message.setRecipient(Message.RecipientType.TO,new InternetAddress(info.getToAddress()));
// 消息发送的时间
message.setSentDate(new Date());
return message ;
}
}
4. 后端代码(qceXeE带例子版)
4.1 Controller层
@Operation(summary = "设置并发送忘记密码的验证码")
@PostMapping("/sendForgetPasswordCode")
public ResultReturn sendForgetPasswordCode(String email) throws MyException {
return userService.sendForgetCode(email);
}
4.2 ServiceImpl层
这里我都配置到系统里去了,每次就不用管理员手动发送,只要用户发个请求,系统就能自动生成并发送验证码。
里面的工具类还有一些方法,可以查阅上面通用版里面的代码,这里我就不赘述了。
@Override
public ResultReturn sendForgetCode(String email) throws MyException {
if(!CheckMail.checkMail(email)){
throw new MyException(400,WRONG_EMAIL_ADDRESS);
}
String num = ""+RandomUtil.Code();
redisUtil.setRedisKey("forgetCode", num, 60*5); //先存入redis
SendEmailVO sendEmailVO = new SendEmailVO();
sendEmailVO.setManageType("System");
sendEmailVO.setManager("ForgetPasswordSystem");
sendEmailVO.setModelName("forgetCode"); //需要用的模版名字
Map map = new HashMap
map.put("code",num);
sendEmailVO.setParameters(map);
sendEmailVO.setTitle("诗云-忘记密码-验证码");
sendEmailVO.setToAddress(email);
sendEmailService.sendEmailByParam(sendEmailVO);
return ResultReturnUtil.success(SEND_VERIFICATION_CODE_SUCCESS,email);
}
5. html邮件内容
5.1 注册验证码模板
https://jb51.net/article/180220.htm
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~