目录
本案例实现功能:
1 根据手机号码生成6位数的数字验证码
2 输入手机号和验证码,判断输入的验证码是否正确
1 添加依赖
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-cache</artifactId>
- </dependency>
2 启用缓存

3 实体类
- package com.qing.bean;
-
- import lombok.Data;
-
- @Data
- public class SMSCode {
-
- private String phoneNum;
- private String code;
-
- }
4 创建验证码的工具类
- package com.qing.util;
-
- import org.springframework.cache.annotation.Cacheable;
- import org.springframework.stereotype.Component;
-
- @Component
- public class CodeUtils {
- public String generate(String phoneNum) {
- int hash = phoneNum.hashCode();
- int encryption = 2022630;
- //异或加密:一种通过异或运算进行加密的算法
- //转成二进制,运算规则:相同为0,不同为1,再转成十进制
- long result = hash ^ encryption;
- long nowTime = System.currentTimeMillis();
- result = result ^ nowTime;
- long code = result % 1000000;
- //处理有负数的情况
- code = code < 0 ? -code : code;
- //六位数:前面补0
- String.format("%06d",code);
- return code + "";
- }
-
- //获取缓存里的验证码
- @Cacheable(key ="#phoneNum" ,value = "cacheCode")
- public String getCacheCode(String phoneNum){
- return null;
- }
- }
说明:getCacheCode()获取缓存里的验证码的方法,写在工具类这里是因为要使spring的@Cacheable这个注解生效,需要注入spring容器,该工具类在后面的ServiceImpl进行了注入,该方法返回的是注解@Cacheable的value属性值 → cacheCode (详见后面的测试)


5 service
- package com.qing.service;
-
- import com.qing.bean.SMSCode;
-
- public interface SMSCodeService {
-
- //发送验证码
- String sendCode(String phoneNum);
- //检查验证码
- boolean checkCode(SMSCode smsCode);
- }
6 serviceImpl
- package com.qing.service.impl;
-
- import com.qing.bean.SMSCode;
- import com.qing.service.SMSCodeService;
- import com.qing.util.CodeUtils;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.cache.annotation.CachePut;
- import org.springframework.stereotype.Service;
-
- @Service
- public class SMSCodeServiceImpl implements SMSCodeService {
-
-
- @Autowired
- CodeUtils codeUtils;
-
- //发送验证码
- @Override
- //只往里放,不往外读
- @CachePut(key = "#phoneNum", value = "cacheCode")
- public String sendCode(String phoneNum) {
- return codeUtils.generate(phoneNum);
- }
-
-
- //比对验证码
- @Override
- public boolean checkCode(SMSCode smsCode) {
- //取出内存中的验证码与传递过来的验证码比对,相同返回true
- String code = smsCode.getCode();
- String cacheCode = codeUtils.getCacheCode(smsCode.getPhoneNum());
- return code.equals(cacheCode);
- }
- }
7 controller
- package com.qing.controller;
-
- import com.qing.bean.SMSCode;
- import com.qing.service.SMSCodeService;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.web.bind.annotation.*;
-
- @RestController
- @RequestMapping("/sms")
- public class SMSCodeController {
-
- @Autowired
- private SMSCodeService smsCodeService;
-
- @GetMapping("/{phoneNum}")
- public String getCode(@PathVariable String phoneNum){
-
- return smsCodeService.sendCode(phoneNum);
- }
-
- @PostMapping
- public boolean checkCode(@RequestBody SMSCode smsCode) {
- return smsCodeService.checkCode(smsCode);
- }
- }
1 生成验证码

2 输入错的验证码验证



3 输入正确的验证码

4 再次生成验证

在默认缓存案例的基础上做3个配置就行
1 加依赖
- <dependency>
- <groupId>net.sf.ehcache</groupId>
- <artifactId>ehcache</artifactId>
- </dependency>
2 配置文件

3 ehcache.xml放在resources下
默认缓存

配置新的缓存:name要和@CachePut注解的的value的属性值一样


下图表示的信息:
1 下面的时间分别表示最后一次访问是第几秒访问的
2 上面的数字表示访问了几次
LRU:age → 是上次访问离现在的时间最远的
LFU:gender → 访问次数最少的

在默认缓存的基础加2个配置
1 导入依赖
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
2 配置文件

测试
打开redis的服务端和客户端
生成一次验证码

数据已经进到redis缓存里了
把缓存的名字即这个value属性的值 和 key 电话号码组合成一个新的key一起放进redis缓存里
再生成一次验证码

redis又多了一个缓存数据

测有效时间 10s

看一下测试效果


10s之后缓存里的验证码失效了
备注:超过了有效时长,redis数据里就没有那个缓存了
测前缀



总结
