SpringBoot
【黑马程序员SpringBoot2全套视频教程,springboot零基础到项目实战(spring boot2完整版)】
SpringBoot 开发实用篇
文章目录
- SpringBoot
- SpringBoot 开发实用篇
- 5 整合第三方技术
- 5.3 手机验证码案例 - 生成验证码
- 5.3.1 SpringBoot 的缓存方案
- 5.3.2 缓存使用案例 —— 手机验证码
5 整合第三方技术
5.3 手机验证码案例 - 生成验证码
5.3.1 SpringBoot 的缓存方案
SpringBoot提供的缓存技术除了提供默认的缓存方案,还可以对其他缓存技术进行整合,统一接口,方便缓存技术的开发与管理
刚刚我们做的就是用SpringBoot 默认的缓存技术实现的
在李老师录制课程那会儿,SpringBoot 可以整合的缓存技术
- Generic
- JCache
- Ehcache
- Hazelcast
- Infinispan
- Couchbase
- Redis
- Caffeine
- Simple(默认)
- memcached【市面常用】
5.3.2 缓存使用案例 —— 手机验证码
需求:
- 输入手机号获取验证码,组织文档以短信形式发送给用户(页面模拟)
- 输入手机号和验证码验证结果
需求分析:
- 提供controller,传入手机号,业务层通过手机号计算出独有的6位验证码数据,存入缓存后返回此数据
- 提供controller,传入手机号与验证码,业务层通过手机号从缓存中读取验证码与输入验证码进行比对,返回比对结果
【直接开干】
创建一个新的实体类【验证码】
package com.dingjiaxiong.domain;
import lombok.Data;
/**
* ClassName: SMSCode
* date: 2022/10/21 13:46
*
* @author DingJiaxiong
*/
@Data
public class SMSCode {
private String tele;
private String code;
}
直接做业务层【因为我们不用去数据库拿数据】
package com.dingjiaxiong.service;
import com.dingjiaxiong.domain.SMSCode;
/**
* ClassName: SMSCodeService
* date: 2022/10/21 13:47
*
* @author DingJiaxiong
*/
public interface SMSCodeService {
//模拟发送验证码到手机
public String sendCodeToSMS(String tele);
//校验验证码
public boolean checkCode(SMSCode smsCode);
}
先来一个生成6位加密验证码的“小工具类”
package com.dingjiaxiong.utils;
import org.springframework.stereotype.Component;
/**
* ClassName: CodeUtils
* date: 2022/10/21 13:53
*
* @author DingJiaxiong
*/
@Component
public class CodeUtils {
private String[] patch = {"000000","00000","0000","000","00","0",""};
public String generator(String tele){
int hash = tele.hashCode();
int encryption = 20206666;
long result = hash ^ encryption; //异或
long nowTime = System.currentTimeMillis();
result = result ^ nowTime; //与系统当前时间再次异或
long code = result % 1000000; //取加密后的后六位
code = code < 0 ? -code : code ; //负数特殊处理
String codeStr = code + "";//可能还得补0
int len = codeStr.length();
return patch[len] + codeStr;
}
// public static void main(String[] args) {
// System.out.println(new CodeUtils().generator("18866668888"));
// }
}
业务层实现类
package com.dingjiaxiong.service.impl;
import com.dingjiaxiong.domain.SMSCode;
import com.dingjiaxiong.service.SMSCodeService;
import com.dingjiaxiong.utils.CodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
/**
* ClassName: SMSCodeServiceImpl
* date: 2022/10/21 13:50
*
* @author DingJiaxiong
*/
@Service
public class SMSCodeServiceImpl implements SMSCodeService {
@Autowired
private CodeUtils codeUtils;
@Override
@Cacheable(value = "smsCode" ,key = "#tele")
public String sendCodeToSMS(String tele) {
String code = codeUtils.generator(tele);
return code;
}
@Override
public boolean checkCode(SMSCode smsCode) {
return false;
}
}
校验还没写
控制器
package com.dingjiaxiong.controller;
import com.dingjiaxiong.domain.SMSCode;
import com.dingjiaxiong.service.SMSCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* ClassName: SMSCodeController
* date: 2022/10/21 13:51
*
* @author DingJiaxiong
*/
@RestController
@RequestMapping("/sms")
public class SMSCodeController {
@Autowired
private SMSCodeService smsCodeService;
@GetMapping
public String getCode(String tele){
String code = smsCodeService.sendCodeToSMS(tele);
return code;
}
@PostMapping
public boolean checkCode(SMSCode code){
return smsCodeService.checkCode(code);
}
}
直接启动服务器
直接测试一下生成验证码
这样就得到了一个验证码,再发一次
并没有变化好家伙,验证码过期机制没了
什么原因
这是因为业务层中
第一次访问,生成一个code 存入缓存后,下一次再访问时,检测到手机号没变,直接返回了第一次生成的验证码。这显然是不符合常理的【这样就可以看到@Cacheable 这个注解在现在这个场景下就不适用了】
我们需要仅仅在把单次操作放到缓存,但是不要主动去读
换一个
@CachePut(value = "smsCode" ,key = "#tele")
这个就没有取的操作了
重启服务器,再试一次
这样就每次都不一样了
【OK,这样第一步就完成了,生成验证码,并且“放入”缓存】