1.首先导入依赖
org.springframework.boot
spring-boot-starter-mail
//redis依赖
org.springframework.boot
spring-boot-starter-data-redis
2.7.5
org.springframework.session
spring-session-data-redis
2.7.0
进行redis的配置
@Configuration
public class RedisTemplateConfig {
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
redisTemplate.setKeySerializer(RedisSerializer.string());
return redisTemplate;
}
}
@Configuration
@ConfigurationProperties(prefix = "spring.redis")
@Data
public class RedissonConfig {
private String host;
private String port;
@Bean
public RedissonClient redissonClient(){
// 创建配置
Config config = new Config();
String redisAdress=String.format("redis://%s:%s",host,port);
//setdatebase是指redis库号
config.useSingleServer().setAddress(redisAdress).setDatabase(3);
//创建实例
RedissonClient redisson = Redisson.create(config);
return redisson;
}
}
appliication.yml
redis的配置
#Resdis配置
redis:
port: 6379
host: localhost
database: 3
邮箱的配置
spring
mail:
host: smtp.qq.com
username: 你的邮箱账号
password: 开通POP3之后会给你一个字符串
default-encoding: utf-8
properties:
mail:
smtp:
auth: true
starttls:
enable: true
required: true
2.进入qq邮箱电脑端(设置-账户),开启服务
3.在usercontroller中创建接口
@PostMapping("/sendMessage")
public BaseResponse sendMessage(@RequestBody UserSendMessage userSendMessage) {
log.info("userSendMessage:"+userSendMessage.toString());
return userService.sendMessage(userSendMessage);
}
创建实体类userSendMessage
@Data
public class UserSendMessage implements Serializable {
private static final long serialVersionUID = 46412442243484364L;
private String userEmail;
private String code;
}
随机生成验证码
package com.kuang.utils;
import java.util.Random;
/**
* 随机生成验证码工具类
*/
public class ValidateCodeUtils {
/**
* 随机生成验证码
*
* @param length 长度为4位或者6位
* @return
*/
public static Integer generateValidateCode(int length) {
Integer code = null;
if (length == 4) {
code = new Random().nextInt(9999);//生成随机数,最大为9999
if (code < 1000) {
code = code + 1000;//保证随机数为4位数字
}
} else if (length == 6) {
code = new Random().nextInt(999999);//生成随机数,最大为999999
if (code < 100000) {
code = code + 100000;//保证随机数为6位数字
}
} else {
throw new RuntimeException("只能生成4位或6位数字验证码");
}
return code;
}
/**
* 随机生成指定长度字符串验证码
*
* @param length 长度
* @return
*/
public static String generateValidateCode4String(int length) {
Random rdm = new Random();
String hash1 = Integer.toHexString(rdm.nextInt());
String capstr = hash1.substring(0, length);
return capstr;
}
}
实现sendMessage方法,将验证码写入redis,为后面的用户注册校验验证码做准备
/**
* 发送验证码
* @param toEmail
* @return
*/
@Override
public BaseResponse sendMessage(UserSendMessage toEmail) {
String email = toEmail.getUserEmail();
if (StringUtils.isEmpty(email)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "email为空");
}
String subject = "****系统";
String code = "";
//StringUtils.isNotEmpty字符串非空判断
if (StringUtils.isNotEmpty(email)) {
//发送一个四位数的验证码,把验证码变成String类型
code = ValidateCodeUtils.generateValidateCode(6).toString();
String text = "【***系统】您好,您的验证码为:" + code + ",请在5分钟内使用";
log.info("验证码为:" + code);
//发送短信
SimpleMailMessage message = new SimpleMailMessage();
message.setFrom(from);
message.setTo(email);
message.setSubject(subject);
message.setText(text);
//发送邮件
javaMailSender.send(message);
UserSendMessage userSendMessage = new UserSendMessage();
userSendMessage.setUserEmail(email);
userSendMessage.setCode(code);
// 作为唯一标识
String redisKey = String.format("my:user:sendMessage:%s", email);
ValueOperations valueOperations = redisTemplate.opsForValue();
// 写缓存
try {
valueOperations.set(redisKey, userSendMessage, 300000, TimeUnit.MILLISECONDS);
UserSendMessage sendMessage = (UserSendMessage) valueOperations.get(redisKey);
log.info(sendMessage.toString());
return ResultUtils.success(true);
} catch (Exception e) {
log.error("redis set key error", e);
throw new BusinessException(ErrorCode.SYSTEM_ERROR, "缓存失败!");
}
}
return ResultUtils.success(true);
}
}
用户注册功能
@PostMapping("/register")
public BaseResponse userRegister(@RequestBody UserRegisterRequest userRegisterRequest){
if (userRegisterRequest == null){
throw new BusinessException(ErrorCode.PARAMS_ERROR);
}
String userAccount = userRegisterRequest.getUserAccount();
String userPassword = userRegisterRequest.getUserPassword();
String checkPassword = userRegisterRequest.getCheckPassword();
String planetCode=userRegisterRequest.getPlanteCode();
String userEmail = userRegisterRequest.getUserEmail();
String code = userRegisterRequest.getCode();
if (StringUtils.isAnyBlank(userAccount,userPassword,checkPassword,planetCode,code,userEmail)){
throw new BusinessException(ErrorCode.NULL_ERROR,"不存在");
}
long result= userService.userRegister(userAccount,userPassword,checkPassword,planetCode,code,userEmail);
// return new BaseResponse<>(0,result,"ok");
return ResultUtils.success(result);
注册功能的实现
//把yml配置的邮箱号赋值到from
@Value("${spring.mail.username}")
private String from;
//发送邮件需要的对象
@Resource
private JavaMailSender javaMailSender;
@Resource
private RedisTemplate redisTemplate;
@Override
public long userRegister(String userAccount, String userPassword, String checkPassword,String planetCode,String code,String userEmail) {
//同时判断三个参数是否为空
if (StringUtils.isAnyBlank(userAccount,userPassword,checkPassword,planetCode,code,userEmail)){
throw new BusinessException(ErrorCode.PARAMS_ERROR,"参数为空");
}
//检验长度
if(userAccount.length()<4){
throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户账号过短");
}
if (planetCode.length()>5){
throw new BusinessException(ErrorCode.PARAMS_ERROR,"星球账号过大");
}
if (userPassword.length()<8 || checkPassword.length()<8){
throw new BusinessException(ErrorCode.PARAMS_ERROR,"用户密码过短");
}
//账户不能包含特殊字符
// String validPattern= "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>/?~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]";
String validPattern = "[`~!@#$%^&*()+=|{}':;',\\\\[\\\\].<>~!@#¥%……&*()——+|{}【】‘;:”“’。,、?]";
Matcher matcher = Pattern.compile(validPattern).matcher(userAccount);
if (matcher.find()){
throw new BusinessException(ErrorCode.PARAMS_ERROR,"含特殊字符");
}
//密码和校验密码相同
if (!userPassword.equals(checkPassword)){
throw new BusinessException(ErrorCode.PARAMS_ERROR,"两次密码输入不同");
}
//从ression获取验证码
String redisKey = String.format("my:user:sendMessage:%s", userEmail);
ValueOperations valueOperations = redisTemplate.opsForValue();
log.info(redisKey);
UserSendMessage sendMessage = (UserSendMessage) valueOperations.get(redisKey);
//如果没有值,失败
if (!Optional.ofNullable(sendMessage).isPresent()) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "获取验证码失败!");
}
//比对验证码
String sendMessageCode = sendMessage.getCode();
log.info(sendMessageCode);
if (!code.equals(sendMessageCode)) {
throw new BusinessException(ErrorCode.PARAMS_ERROR, "验证码不匹配!");
}
//账户不能重复使用,检验数据库中的数据是否与新创建的用户是否相同
QueryWrapper queryWrapper=new QueryWrapper<>();
//获取用户
queryWrapper.eq("userAccount",userAccount);
//计算用户数量
long count = userMapper.selectCount(queryWrapper);
log.info(count+"");
if (count>0){
throw new BusinessException(ErrorCode.PARAMS_ERROR,"存在重复用户");
}
//星球编号不能重复使用
queryWrapper=new QueryWrapper<>();
queryWrapper.eq("planetCode",planetCode);
count = userMapper.selectCount(queryWrapper);
if (count>0){
throw new BusinessException(ErrorCode.PARAMS_ERROR,"编号重复");
}
//加密密码,MD5算法加密
String newPassword= DigestUtils.md5DigestAsHex((SALT+userPassword).getBytes());
//向数据库中插入数据
User user = new User();
user.setUserAccount(userAccount);
user.setUserPassword(newPassword);
user.setPlanetCode(planetCode);
user.setEmail(userEmail);
boolean saveResult= this.save(user);
if (!saveResult){
throw new BusinessException(ErrorCode.PARAMS_ERROR,"不存在用户");
}
return user.getId();
}
qq邮箱的实现主要是发送消息后将消息缓存到redis,在用户进行注册的时候,将填写的验证码和缓存中的数据进行校验,如果相同实现注册,验证码正确。