博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【java小程序实战】redis缓存session的实现
阅读量:4185 次
发布时间:2019-05-26

本文共 12703 字,大约阅读时间需要 42 分钟。

###内容目录(由[TOC]自动生成)

文章目录

一、有状态session

当用户访问web网站的时候,会产生一个session,维护这用户和系统的关系

二、无状态session

当app端的用户访问网站的时候,没有session这个会话,无法维护用户和系统的关系。

三、redis-session

1、用户信息存储到redis中,形成无状态会话。

2、便于扩展,当单体应用扩展成集群会相当方便。
3、便于权限验证。

四、redis应用

先去官网下载redis版本,并安装,关于安装的教程,大家可以自行百度。

1、pom依赖

org.springframework.boot
spring-boot-starter-data-redis
redis.clients
jedis
2.9.0
org.springframework.data
spring-data-redis
1.8.7.RELEASE

2、application.properties redis的配置

############################################################## redis 配置############################################################## Redis 数据库索引(默认为0)spring.redis.database=1# Redis服务器地址spring.redis.host=localhost# Redis服务器端口号spring.redis.port=6379#Redis 服务器连接密码(默认为空)spring.redis.password=# 连接池最大连接数(使用负值表示没有限制)spring.redis.pool.max-active=1000#连接池最大阻塞等待时间(使用负值表示没有限制)spring.redis.pool.max-wait=-1#  连接池中最大空闲连接spring.redis.pool.max-idle=10# 连接池中的最小空闲连接spring.redis.pool.min-idle=2# 连接超时时间(毫秒)spring.redis.timeout=0

3、redis的一个工具类

package com.imooc.utils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.redis.core.StringRedisTemplate;import org.springframework.stereotype.Component;import java.util.Map;import java.util.Set;import java.util.concurrent.TimeUnit;/** *   使用redisTemplate 的操作实现类 */@Componentpublic class RedisOperator {    @Autowired    private StringRedisTemplate stringRedisTemplate;     // Key (键),简单的 key-value操作    /**     *  实现命令:TTL key, 以秒为单位,返回给定的key的剩余时间)(ttl,time to live)     * @param key     * @return     */    public long ttl(String key){        return stringRedisTemplate.getExpire(key);    }    /**     *  实现命令: expire ,设置过期时间,单位秒     * @param key     * @param timeout     */    public void expire(String key, long timeout) {        stringRedisTemplate.expire(key, timeout, TimeUnit.SECONDS);    }    /**     * 实现命令: incr key ,增加key 一次     * @param key     * @param delta     * @return     */    public long incr(String key, long delta){        return stringRedisTemplate.opsForValue().increment(key,delta);    }    /**     * 实现命令:KEYS pattern, 查找所有符合给定模式 pattern 的key     * @param pattern     * @return     */    public Set
keys(String pattern){ return stringRedisTemplate.keys(pattern); } /** * 实现命令:DEL key ,删除一个key * @param key */ public void del(String key){ stringRedisTemplate.delete(key); } /** * 实现命令: SET key value,设置一个key-value(将字符串值value 关联到key) * @param key * @param value */ public void set(String key, String value){ stringRedisTemplate.opsForValue().set(key, value); } /** * 实现命令:SET key value time,设置一个key-value 过期时间。 * @param key * @param value * @param time */ public void set(String key, String value, long time){ stringRedisTemplate.opsForValue().set(key, value, time); } /** * 实现命令: GET key,返回key所关联的字符串值 * @param key * @return */ public String get(String key){ return (String)stringRedisTemplate.opsForValue().get(key); } // Hash (哈希表) /** * 实现命令: HSET key field value ,将哈希表key 中的域 field 的值设为value * @param key * @param field * @param value */ public void hset(String key, String field, Object value){ stringRedisTemplate.opsForHash().put(key, field, value); } /** * 实现命令:HGET key field,返回哈希表 key中给定域field的值 * @param key * @param field * @return */ public String hget(String key, String field){ return (String) stringRedisTemplate.opsForHash().get(key, field); } /** * 实现命令: HDEL key field[field...],删除哈希表 key 中的一个或多个指定域,不存在的域将被忽略。 * @param key * @param fields */ public void hdel(String key, Object... fields){ stringRedisTemplate.opsForHash().delete(key, fields); } /** * 实现命令: HGETALL key,返回哈希表 key中,所有的域和值 * @param key * @return */ public Map
hgetall(String key){ return stringRedisTemplate.opsForHash().entries(key); } //List (列表) /** * 实现命令: LPUSH key value,将一个值value 插入到列表 key 的表头 * @param key * @param value * @return */ public long lpush(String key, String value){ return stringRedisTemplate.opsForList().leftPush(key, value); } /** * 实现命令:LPOP key,移出并返回列表 key的头元素。 * @param key * @return */ public String lpop(String key) { return (String)stringRedisTemplate.opsForList().leftPop(key); } /** * 实现命令:RPUSH key value ,将一个值value 插入到列表 key 的表尾 * @param key * @param value * @return */ public long rpush(String key, String value){ return stringRedisTemplate.opsForList().rightPush(key, value); }}

4、在api模块,新建一个vo包,创建UsersVo对象,添加了一个userToken属性。

package com.imooc.pojo.vo;import io.swagger.annotations.ApiModel;import io.swagger.annotations.ApiModelProperty;import javax.persistence.Column;import javax.persistence.Id;@ApiModel(value = "用户对象" ,description = "这是用户对象")public class UsersVo {    @ApiModelProperty(hidden = true)    private String id;    @ApiModelProperty(hidden = true)    private String userToken;    /**     * 用户名     */    @ApiModelProperty(value = "用户名" , name = "username" , example = "csdnuser" ,required = true)    private String username;    /**     * 密码     */    @ApiModelProperty(value = "密码" , name = "password" , example = "123456" ,required = true)    private String password;    /**     * 我的头像,如果没有默认给一张     */    @ApiModelProperty(hidden = true)    private String faceImage;    /**     * 昵称     */    private String nickname;    /**     * 我的粉丝数量     */    @ApiModelProperty(hidden = true)    private Integer fansCounts;    /**     * 我关注的人总数     */    @ApiModelProperty(hidden = true)    private Integer followCounts;    /**     * 我接受到的赞美/收藏 的数量     */    @ApiModelProperty(hidden = true)    private Integer receiveLikeCounts;    /**     * @return id     */    public String getId() {        return id;    }    /**     * @param id     */    public void setId(String id) {        this.id = id;    }    /**     * 获取用户名     *     * @return username - 用户名     */    public String getUsername() {        return username;    }    /**     * 设置用户名     *     * @param username 用户名     */    public void setUsername(String username) {        this.username = username;    }    /**     * 获取密码     *     * @return password - 密码     */    public String getPassword() {        return password;    }    /**     * 设置密码     *     * @param password 密码     */    public void setPassword(String password) {        this.password = password;    }    /**     * 获取我的头像,如果没有默认给一张     *     * @return face_image - 我的头像,如果没有默认给一张     */    public String getFaceImage() {        return faceImage;    }    /**     * 设置我的头像,如果没有默认给一张     *     * @param faceImage 我的头像,如果没有默认给一张     */    public void setFaceImage(String faceImage) {        this.faceImage = faceImage;    }    /**     * 获取昵称     *     * @return nickname - 昵称     */    public String getNickname() {        return nickname;    }    /**     * 设置昵称     *     * @param nickname 昵称     */    public void setNickname(String nickname) {        this.nickname = nickname;    }    /**     * 获取我的粉丝数量     *     * @return fans_counts - 我的粉丝数量     */    public Integer getFansCounts() {        return fansCounts;    }    /**     * 设置我的粉丝数量     *     * @param fansCounts 我的粉丝数量     */    public void setFansCounts(Integer fansCounts) {        this.fansCounts = fansCounts;    }    /**     * 获取我关注的人总数     *     * @return follow_counts - 我关注的人总数     */    public Integer getFollowCounts() {        return followCounts;    }    /**     * 设置我关注的人总数     *     * @param followCounts 我关注的人总数     */    public void setFollowCounts(Integer followCounts) {        this.followCounts = followCounts;    }    /**     * 获取我接受到的赞美/收藏 的数量     *     * @return receive_like_counts - 我接受到的赞美/收藏 的数量     */    public Integer getReceiveLikeCounts() {        return receiveLikeCounts;    }    /**     * 设置我接受到的赞美/收藏 的数量     *     * @param receiveLikeCounts 我接受到的赞美/收藏 的数量     */    public void setReceiveLikeCounts(Integer receiveLikeCounts) {        this.receiveLikeCounts = receiveLikeCounts;    }    public String getUserToken() {        return userToken;    }    public void setUserToken(String userToken) {        this.userToken = userToken;    }}

5、创建一个BasicController

package com.imooc.controller;import com.imooc.utils.RedisOperator;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.RestController;@RestControllerpublic class BasicController {    @Autowired    public RedisOperator redis;    public  static final  String USER_REDIS_SESSION  = "user-redis-session";}

5、对RegistLoginController进行修改

package com.imooc.controller;import com.imooc.imoocvideosdevservice.com.imooc.service.UserService;import com.imooc.pojo.Users;import com.imooc.pojo.vo.UsersVo;import com.imooc.utils.IMoocJSONResult;import com.imooc.utils.MD5Utils;import io.swagger.annotations.Api;import io.swagger.annotations.ApiOperation;import org.apache.commons.lang3.StringUtils;import org.springframework.beans.BeanUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RestController;import java.security.NoSuchAlgorithmException;import java.util.UUID;//返回格式为json格式@RestController@Api(value = "用户注册登陆的接口" , tags = {"注册和登陆的controller"})public class RegistLoginController extends BasicController {    @Autowired    private UserService userService;    @ApiOperation(value = "用户注册", notes = "用户注册的接口")    @PostMapping("/regist")    public IMoocJSONResult regist(@RequestBody Users user) throws Exception {        System.out.println("username:"+user.getUsername()+"password:"+user.getPassword());      //1、判断用户名和密码是否为空        if(StringUtils.isBlank(user.getUsername()) || StringUtils.isBlank(user.getPassword())){            return IMoocJSONResult.errorMsg("用户名和密码不能为空");        }        //2、判断用户名是否存在         boolean usernameIsExist = userService.queryUsernameIsExist(user.getUsername());        //3、保存用户,注册信息        if(!usernameIsExist){            user.setNickname(user.getUsername());            user.setPassword(MD5Utils.getMD5Str(user.getPassword()));            user.setReceiveLikeCounts(0);            user.setFansCounts(0);            user.setFollowCounts(0);            userService.saveUser(user);        }else{            return IMoocJSONResult.errorMsg("用户名已经存在");        }        //在注册完毕,将用户数据返回给前端之前,为了安全,将密码设为null        user.setPassword("");        //使用uuid,设置用户的value//        String uniqueToken = UUID.randomUUID().toString();//        redis.set(USER_REDIS_SESSION + ":" + user.getId(), uniqueToken, 1000 * 60 * 30);//        UsersVo usersVo = new UsersVo();//        BeanUtils.copyProperties(user, usersVo);//        usersVo.setUserToken(uniqueToken);        // 绑定用户信息到redis        UsersVo usersVo = setUserRedisSessionToken(user);        return IMoocJSONResult.ok(usersVo);    }    @ApiOperation(value= "用户登陆" , notes = "用户登陆接口")    @PostMapping("/login")    public IMoocJSONResult login(@RequestBody Users users) throws NoSuchAlgorithmException, InterruptedException {        Thread.sleep(3000);           String username = users.getUsername();           String password = users.getPassword();           //1、判断用户名和密码不能为空        if (StringUtils.isBlank(username) || StringUtils.isBlank(password)){            return IMoocJSONResult.errorMsg("用户名和密码不能为空");        }        // 2、判断用户是否存在        Users userResult = userService.queryUserForLogin(username,MD5Utils.getMD5Str(password));        //3、返回        if (userResult !=null ){            //密码设置为null,返回给前端            userResult.setPassword("");            //将用户信息进行redis设置            UsersVo usersVo = setUserRedisSessionToken(userResult);            return IMoocJSONResult.ok(usersVo);        } else {            return IMoocJSONResult.errorMsg("用户名或密码不正确,请重试...");        }    }    /**     * 将用户信息进行redis设置     * @param userModel     * @return     */    public UsersVo setUserRedisSessionToken(Users userModel){        //使用uuid,设置用户的value        String uniqueToken = UUID.randomUUID().toString();        redis.set(USER_REDIS_SESSION + ":" + userModel.getId(), uniqueToken, 1000 * 60 * 30);        UsersVo usersVo = new UsersVo();        BeanUtils.copyProperties(userModel, usersVo);        usersVo.setUserToken(uniqueToken);        return usersVo;    }}

现在我们就可以重启后端代码,通过小程序访问。之后可以在Redis-Desktop Manager工具中查看,缓存的用户信息。

备注: 在controller中我们通过 一个 :(冒号)将同一类信息,归属到同一个文件夹下。

在这里插入图片描述

转载地址:http://jjfoi.baihongyu.com/

你可能感兴趣的文章
java日志组件介绍(common-logging,log4j,slf4j,logback )
查看>>
java运行jar命令提示没有主清单属性
查看>>
使用Maven为一个项目生成多个Jar包,将一个目录打成jar包
查看>>
CMD命令名详细大全
查看>>
C、C++、MATLAB、Python、Go 哪个比较适合写算法
查看>>
Spring的一个命名空间的名称空间处理程序没有找到
查看>>
Maven常用插件配置和使用
查看>>
spring.schemas、spring.handlers的使用
查看>>
命名空间
查看>>
数据总线技术框架说明
查看>>
ifconfig和ipconfig有什么区别
查看>>
linux配置ip地址后重启哪个服务
查看>>
git的安装
查看>>
Sublime 和webstorm的区别
查看>>
dblink是什么
查看>>
Greenplum数据库的dblink功能之搭建
查看>>
数据库的模式
查看>>
spark与storm的对比
查看>>
感悟20170302
查看>>
Git服务器 及gitolite的搭建及简单操作
查看>>