在上一节中,实现了 SpringBoot + redis 的整合,因此在这里只列出必要部分的 redis 代码。
<!-- redis --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
spring.redis.port=6379 spring.redis.host=127.0.0.1 spring.redis.password=123456 # 数据库索引(默认为0) spring.redis.database=15 #最大连接数(使用负值表示没有限制) spring.redis.jedis.pool.max-active=100 #最大空闲连接 spring.redis.jedis.pool.max-idle=8 #最小空闲连接 spring.redis.jedis.pool.min-idle=0 #最大阻塞等待时间(使用负值表示没有限制) spring.redis.jedis.pool.max-wait=60000 #连接超时时间 spring.redis.timeout=1000
@Configuration public class RedisConfig { @Bean public RedisTemplate<String, Object> template(RedisConnectionFactory factory) { //创建RedisTemplate<String,Object>对象 RedisTemplate<String, Object> template = new RedisTemplate<>(); //配置连接工厂 template.setConnectionFactory(factory); //定义Jackson2JsonRedisSerializer序列化对象 Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper objectMapper = new ObjectMapper(); //指定要序列化的域,field,get和set,以及修饰符范围,ANY是包括private到public objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); //指定序列化输入的类型,类必须是非final修饰的,final修饰的类如String,Integer会报异常 objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL); jsonRedisSerializer.setObjectMapper(objectMapper); StringRedisSerializer stringRedisSerializer = new StringRedisSerializer(); // 值采用json序列化 template.setValueSerializer(jsonRedisSerializer); //使用StringRedisSerializer来序列化和反序列化redis的key值 template.setKeySerializer(new StringRedisSerializer()); // 设置hash key 和value序列化模式 template.setHashKeySerializer(new StringRedisSerializer()); template.setHashValueSerializer(jsonRedisSerializer); template.afterPropertiesSet(); return template; } }
@Component public class RedisUtils { @Autowired private RedisTemplate<String, Object> redisTemplate; /** * 指定缓存失效时间 * * @param key 键 * @param time 时间 * @param timeUnit 时间单位 * @return */ public boolean expire(String key, long time, TimeUnit timeUnit) { try { if (time > 0) { redisTemplate.expire(key, time, timeUnit); } return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 根据key 获取过期时间 * * @param key 键 不能为null * @return 时间(秒) 返回0代表为永久有效 */ public long getExpire(String key) { return redisTemplate.getExpire(key, TimeUnit.SECONDS); } /** * 判断key是否存在 * * @param key 键 * @return true 存在 false不存在 */ public boolean hasKey(String key) { try { return redisTemplate.hasKey(key); } catch (Exception e) { e.printStackTrace(); return false; } } /** * 删除缓存 * * @param key 可以传一个值 或多个 */ @SuppressWarnings("unchecked") public void del(String... key) { if (key != null && key.length > 0) { if (key.length == 1) { redisTemplate.delete(key[0]); } else { redisTemplate.delete(CollectionUtils.arrayToList(key)); } } } //============================String============================= /** * 普通缓存获取 * * @param key 键 * @return 值 */ public Object get(String key) { return key == null ? null : redisTemplate.opsForValue().get(key); } /** * 普通缓存放入 * * @param key 键 * @param value 值 * @return true成功 false失败 */ public boolean set(String key, Object value) { try { redisTemplate.opsForValue().set(key, value); return true; } catch (Exception e) { e.printStackTrace(); return false; } } /** * 普通缓存放入并设置时间 * * @param key 键 * @param value 值 * @param time 时间 time要大于0 如果time小于等于0 将设置无限期 * @param timeUnit 时间单位 * @return true成功 false 失败 */ public boolean set(String key, Object value, long time, TimeUnit timeUnit) { try { if (time > 0) { redisTemplate.opsForValue().set(key, value, time, timeUnit); } else { set(key, value); } return true; } catch (Exception e) { e.printStackTrace(); return false; } }
@GetMapping(value = "/tokenLogin") @ResponseBody public Result tokenLogin(String name, String password) { User user = userService.getOne(new QueryWrapper<User>().eq("name", name)); if (user == null) { return ResultUtil.fail(1, "账号未注册"); } else { //MD5加密 String md5Password = DigestUtils.md5DigestAsHex(password.getBytes()); if (!md5Password.equals(user.getPassword())) { return ResultUtil.fail(2, "密码错误"); } } //生成token String token = UUID.randomUUID().toString().replaceAll("-", ""); //保存token,key为token,value为id,有效期为1个小时 redisUtils.set(token, user.getId(), 1, TimeUnit.HOURS); return ResultUtil.success(token); }
public class AccessFilter implements Filter { Logger logger = LoggerFactory.getLogger(AccessFilter.class); private RedisUtils redisUtils; @Override public void init(FilterConfig filterConfig) throws ServletException { //非Spring管理环境,需要手动注入Bean redisUtils = SpringUtils.getBean(RedisUtils.class); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; //登录接口跳过验证 if (request.getRequestURI().contains("/tokenLogin")) { filterChain.doFilter(request, response); return; } /** token+redis验证 */ String token = request.getHeader("token"); if (!redisUtils.hasKey(token)) { logger.info("token过期,请重新登录"); return; } //刷新token有效期 redisUtils.expire(token, 1, TimeUnit.HOURS); filterChain.doFilter(request, response); } @Override public void destroy() { } }
@GetMapping(value = "/tokenLogout") @ResponseBody public Result tokenLogout(HttpServletRequest request) { String token = request.getHeader("token"); //删除redis的token redisUtils.del(token); return ResultUtil.success(0,"退出成功"); }