上一篇文章中我们了解了Redis的数据类型,接下来进入Redis的实操。
一.springboot集成邮件发送功能
1.引入依赖:
<!--邮箱发送依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
</dependency>
<!--redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--hutool工具类-->
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.12</version>
</dependency>
2.开启qq邮箱发送邮件功能
首先登录qq邮箱,进入设置选项
下拉找到POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务
开启STMP服务,并获取邮箱发送密码(不是qq邮箱的密码,是发送邮件需要的密码)
2.springboot配置email信息
在spring配置信息下新增mail的配置,下面是参考配置
application.yml的参考配置
mail:
username: 你的qq邮箱号
password: 刚刚我们获取的stmp的密码
host: smtp.qq.com
default-encoding: UTF-8
3.引入邮件发送的Util
下面是我当时网上找的一个我认为还不错的一个sendEmailUtils,具体是出自哪篇文章忘了,非常抱歉。
@Component
@Slf4j
public class SendEmailUtils {
@Autowired
private JavaMailSender javaMailSender;
@Value("${spring.mail.username}")
String userName;
/**
* 发送邮箱方法
* @param title 标题
* @param html 发送的html内容
* @param message 发送的信息
*/
public void sendHtml(String title, String html, String message) {
MimeMessage mailMessage = javaMailSender.createMimeMessage();
//需要借助Helper类
MimeMessageHelper helper = new MimeMessageHelper(mailMessage);
try {
helper.setFrom(userName); // 必填
helper.setTo(message); // 必填
// helper.setBcc("密送人"); // 选填
helper.setSubject(title); // 必填
helper.setSentDate(new Date());//发送时间
helper.setText(html, true); // 必填 第一个参数要发送的内容,第二个参数是不是Html格式。
javaMailSender.send(mailMessage);
} catch (MessagingException e) {
log.error("发送邮件失败", e);
throw new RuntimeException(e);
}
}
}
二.springboot集成redis
上面我们已经引入了依赖了,现在我们配置一下Redis
1.application.yml配置Reids
redis:
host: 127.0.0.1
port: 6379
lettuce:
pool:
max-active: 8 #最大连接
max-idle: 8 #最大空闲连接
min-idle: 0 #最小空闲连接
max-wait: 100 #连接等待时间
database: 0
2.个性化配置Redis
@Configuration
public class RedisConfiguration {
@Bean
@Primary
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
// 为了开发方便,一般直接使用<String, Object>
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory);
// 配置具体的序列化方式
// JSON解析任意对象
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper om = new ObjectMapper();
// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
// 设置日期格式
om.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
jackson2JsonRedisSerializer.setObjectMapper(om);
// String的序列化
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//key采用String的序列化
template.setKeySerializer(stringRedisSerializer);
//hash的key也采用String的序列化
template.setHashKeySerializer(stringRedisSerializer);
//value的序列化方式采用jackson
template.setValueSerializer(jackson2JsonRedisSerializer);
//hash的value序列化方式采用jackson
template.setHashValueSerializer(jackson2JsonRedisSerializer);
//设置所有配置
template.afterPropertiesSet();
return template;
}
}
三.整合Redis和email
1.前端内容准备
<div class="layui-form-item">
<input id="send-email-code" name="send-email-code" style="" type="button" class="layui-btn layui-btn layui-btn-normal layui-btn-fluid" value="获取验证码"/>
</div>
var InterValObj; //timer变量,控制时间
var count = 60; //间隔函数,1秒执行
var curCount;//当前剩余秒数
//向邮箱发送验证码
$('#send-email-code').click(function(){
//校验邮箱
var email = $("#email").val();
if(!email.match(/^[a-z0-9]+([._]*[a-z0-9]+)*@[a-z0-9]+([_.][a-z0-9]+)+$/gi)){
layer.msg("邮箱格式不正确!请重新输入", {icon: 5});
return false;
}
// 设置button效果,开始计时
curCount = count;
document.getElementById("send-email-code").setAttribute("disabled","true" );//设置按钮为禁用状态
document.getElementById("send-email-code").value=curCount + "秒后重获";//更改按钮文字
InterValObj = window.setInterval(SetRemainTime, 1000); // 启动计时器timer处理函数,1秒执行一次
//请求发送验证码
$.ajax({
type:"get",
url:"/email/sendEmail",
async:false,
data:{"email":email},
success:function(data){
if(data.code === 200){//验证码发送成功
layer.msg('发送成功', {icon: 1, time: 1000}, function () {
$("#emailCode").removeAttr("style")
});
}else{
layer.msg(data.message, {icon: 5});
}
},
});
});
//timer处理函数
function SetRemainTime() {
if (curCount == 0) {//超时重新获取验证码
window.clearInterval(InterValObj);// 停止计时器
document.getElementById("send-email-code").removeAttribute("disabled");//移除禁用状态改为可用
document.getElementById("send-email-code").value="重获验证码";
}else {
curCount--;
document.getElementById("send-email-code").value=curCount + "秒后重获";
}
}
2.后端整合Redis和email
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
public class EmailServiceImpl implements EmailService {
@Resource
private SendEmailUtils sendEmailUtils;
@Resource
private StringRedisTemplate stringRedisTemplate;
@Override
public Result sendEmail(String email) {
String emailCode = RandomUtil.randomNumbers(6);
log.info("本次验证码为:{}",emailCode);
String context = "<b>尊敬的用户:</b><br><br><br> 您好," +
"校园代取快递系统提醒您本次的验证码是:<b>{}</b>," +
"有效期5分钟。<br><br><br><b>校园代取快递系统</b>";
String html = StrUtil.format(context, emailCode);
//发送邮件
try {
sendEmailUtils.sendHtml("【校园代取快递系统】邮箱注册验证", html, email);
}catch (Exception e){
throw new RuntimeException("邮件发送失败");
}
//将验证码信息存储至redis中并设置过期时间
stringRedisTemplate.opsForValue().set(REGISTER_CODE_KEY+email,emailCode,LOGIN_CODE_TTL, TimeUnit.MINUTES);
Result result = new Result();
result.setCode(NumberUtils.TWO_HUNDRED);
result.setMessage("邮件发送成功");
return result;
}
}
在该方法中我们首先生成了一个随机的六位验证码,然后尝试发送邮件,发送成功后我们将我们的验证码信息存储在Redis中,并设置过期时间,这样我们就能完成邮件发送码,并设置过期时间的功能,在后面我们只需要将前端用户输入的验证码与Redis中的验证码做对比即可判断是否正确。
@Override
public Result<HnUser> register(HnUser user, String type) {
Result result = new Result();
if (StringUtils.isBlank(user.getEmailCode())
|| StringUtils.isBlank(user.getUserEmail()) ){
result.setCode(500);
result.setMessage("邮箱或验证码错误,请重试");
return result;
}
// 判断验证码是否过期
String redisCode = stringRedisTemplate.opsForValue().get(REGISTER_CODE_KEY + user.getUserEmail());
if (StringUtils.isBlank(redisCode)){
result.setCode(500);
result.setMessage("验证码已过期");
return result;
}
if (!redisCode.equals(user.getEmailCode())){
result.setCode(500);
result.setMessage("验证码错误");
}
if("common".equals(type)){
user.setUserRoleId(1);
}else{
user.setUserRoleId(0);
}
// 密码加密
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
user.setUserPassword(passwordEncoder.encode(user.getUserPassword()));
user.setVersionNumber(0);
List<HnUser> hnUserList = userMapper.selectByUserNameList(user);
if(hnUserList.size() != NumberUtils.ZERO){
result.setCode(500);
result.setMessage("当前用户已存在");
return result;
}else{
try {
userMapper.insertSelective(user);
result.setCode(200);
result.setMessage("注册成功");
}catch (Exception e){
throw new RuntimeException(e);
}
}
return result;
}
四.功能演示