首先我们来理一下思路,发送验证码的整个过程,前端输入邮箱账号,点击获取验证码,请求后台接口,由我们的后台java程序将验证码存储在redis并设置相应的过期时间,以及实现发送验证码到邮箱的功能,用户如果填写的自己的邮箱,就能成功获取验证码,进行注册的时候,获取用户输入邮箱对应的验证码与用户输入的验证码进行匹配,匹配成功就进行注册,否则就提示验证码无效。
接下来创建一个springboot项目,这里不多赘述。
要使用邮件服务还需要集成一下相关依赖
在pom.xml文件里添加相关依赖
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-email</artifactId>
<version>1.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>2.7.4</version>
</dependency>
因为需要将验证码需要具有时效性,我们将其保存在redis中,配置RedisTemplate
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
template.setConnectionFactory(factory);
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
template.afterPropertiesSet();
return template;
}
}
进行redis相关配置
spring:
redis:
database: 0
host: localhost
password:
port: 6379
接下来编写我们的邮件发送工具类
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import javax.mail.*;
import javax.mail.internet.*;
import java.io.UnsupportedEncodingException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;
@Component
public class SendMailUtil {
/**
* 验证邮箱格式
* @param email
* @return
*/
public boolean isEmail(String email) {
if (email == null || email.length() < 1 || email.length() > 256) {
return false;
}
Pattern pattern = Pattern.compile("^\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*$");
return pattern.matcher(email).matches();
}
/**
* 发送验证码(可以根据需求更改相应参数)
* @param sender 发送人的邮箱
* @param pwd 邮箱授权码
* @param receiver 收件人
* @param code 验证码
* @return
*/
public String sendEmail(String sender, String pwd, String receiver, String code){
Properties props = new Properties();
props.setProperty("mail.transport.protocol", "smtp"); //使用smpt的邮件传输协议
props.setProperty("mail.smtp.host", "smtpout.secureserver.net"); //主机地址
props.setProperty("mail.smtp.auth", "true"); //授权通过
props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
Session session = Session.getInstance(props);
try {
MimeMessage message = new MimeMessage(session);
// 第二个参数可不填
message.setFrom(new InternetAddress(sender,"sender")); //设置发件人
message.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(recevier,"用户","utf-8")); //设置收件人
message.setSubject("verification code"); //设置主题
message.setSentDate(new Date());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
// 这是我们的邮件内容,可根据需求更改
String str = "<!DOCTYPE html><html><head><meta charset='UTF-8'></head><body><p style='font-size: 20px;font-weight:bold;'>Dear :"+receiver+"</p>"
+ "<p style='text-indent:2em; font-size: 20px;'>Your verification code this time is "
+ "<span style='font-size:30px;font-weight:bold;color:red'>" + code + "</span>,Valid within 60 SECONDS, please use as soon as possible! If not operated by yourself, please ignore!</p>"
+ "<p style='text-align:right; padding-right: 20px;'"
+ "<a href='http://120.79.29.170' style='font-size: 18px'>aof labs</a></p>"
+ "<span style='font-size: 18px; float:right; margin-right: 60px;'>" + sdf.format(new Date()) + "</span></body></html>";
Multipart mul=new MimeMultipart(); //新建一个MimeMultipart对象来存放多个BodyPart对象
BodyPart mdp=new MimeBodyPart(); //新建一个存放信件内容的BodyPart对象
mdp.setContent(str, "text/html;charset=utf-8");
mul.addBodyPart(mdp); //将含有信件内容的BodyPart加入到MimeMultipart对象中
message.setContent(mul); //把mul作为消息内容
message.saveChanges();
//创建一个传输对象
Transport transport=session.getTransport("smtp");
//建立与服务器的链接 465端口是 SSL传输
transport.connect("smtpout.secureserver.net", 465, sender, pwd);
//发送邮件
transport.sendMessage(message,message.getAllRecipients());
//关闭邮件传输
transport.close();
return "验证码发送成功";
} catch (MessagingException | UnsupportedEncodingException e) {
e.printStackTrace();
return "验证码发送失败";
}
}
/**生成随机的六位验证码*/
public StringBuilder CreateCode() {
String dates = "0123456789";
StringBuilder code = new StringBuilder();
Random r = new Random();
for (int i = 0; i < 6; i++) {
int index = r.nextInt(dates.length());
char c = dates.charAt(index);
code.append(c);
}
return code;
}
}
接下来编写我们的接口类(这里我为了图方便直接将业务代码直接将业务代码写在了controller中,规范写法应该是写在servicer层)
@CrossOrigin
@RestController
@RequestMapping("user")
@Api(tags = "userController")
public class UserController {
@Autowired
private UserMapper userMapper
@Autowired
private RedisTemplate redisTemplate;
public SaResult getCode(String receiver){
LambdaQueryWrapper<user> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(user::getEmail,email);
User user= userMapper.selectOne(queryWrapper);
// 首先判断邮箱是否已经注册,已经注册则提示已经注册过了,未注册则继续
if (null != user){
return SaResult.error("此邮箱已经注册过了");
}
// 定义返回消息
String message;
try {
SendMailUtil sendMailUtil = new SendMailUtil();
//判断邮箱格式是否正确
if (sendMailUtil.isEmail(email)) {
// 工具类生成6位随机码
StringBuilder code = sendMailUtil.CreateCode();
ValueOperations<String, String> operations = redisTemplate.opsForValue();
// 如果redis的验证码还存在则提示
if (operations.get(email) != null) {
message = "验证码已发送,请60秒后重试";
} else {
operations.set(email, String.valueOf(code));
// 设置验证码过期时间,可以根据需求调整
redisTemplate.expire(email, 60, TimeUnit.SECONDS);
// 这里填写发送验证码的邮箱账号及授权码
message = sendMailUtil.sendEmail("", "", receiver, String.valueOf(code));
}
} else {
message = "邮箱格式不正确";
}
} catch (Exception e) {
e.printStackTrace();
message = "出现未知错误";
}
return SaResult.data(message);
}
// 邮箱注册
@PostMapping("emailRegister")
@Transactional(rollbackFor = Exception.class)
public SaResult emailRegister(String email, String password, String verifacationCode) {
ValueOperations<String, String> operations = redisTemplate.opsForValue();
// 获取redis中的验证码
String code = operations.get(email);
LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
queryWrapper.eq(User::getEmail, email);
User user= userMapper.selectOne(queryWrapper);
if (user!= null) {
return SaResult.error("邮箱已经注册");
} else {
// 如果验证码正确
if (null != code && code.equals(verifacationCode)){
// 进行正常注册流程
// 删除验证码,保证验证码智能使用一次
redisTemplate.del(email);
return SaResult.ok();
}else {
return SaResult.error("验证码无效,请重新获取");
}
}
}
}
以上就是使用java程序实现发送邮箱验证码并进行邮箱注册的相关代码。