19 简易的基于Redis的SessionManager

这个需求这样的, 我们做一个android的app, 然后 登录使用的是android原生的东西, 然后 之后其他的东西, 是使用html, css, jss来处理的, 具体的细节我也不清楚, 然后 问题是前端拿到sessionId之后, 似乎是由于js的限定, 发送请求的时候, 不能把sessionId放到Cookie头中[具体我没有看, 但是前端大佬过来说, 是这样],, 然后 这样就不能使用服务器自己的session机制了,, 因此 需要自己"实现"一套

然后 自己基于redis自己写了一下, 虽然 没有使用我这个..


基本的思路, 是对于一个属性, 存放两样东西, 第一是其Class的全限定名,第二是给定的对象JSON序列化之后的结果, 然后拿数据的时候, 根据对应的Class进行反序列化, 没有太大的难度, 这里就不太详细的说了, 直接上代码

对了, 这里使用的JSON工具是net.sf.json, 其实使用fastJSON会更加方便一点, 这里需要对于原始类型,String 和其他的自定义类型分开处理

还有这里对于type的处理比较草率, 更加严谨一点, 需要限定setAttribute, getAttribute, removeAttribte, 不能操作type, 通常来说需要使用一些生僻的type的生成, 比如"__age_type"之类的


参考代码



 

package com.hx.util.sessionManager;

import com.hx.log.util.Tools;

import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import redis.clients.jedis.Jedis;

/**
 * RedisSessionManager
 * 
这里为了简单, 直接使用fastJson进行序列化
 *
 * @author Jerry.X.He
 * @version 1.0
 * @date 2017/1/13 14:58
 */
public final class RedisSessionManager implements SessionManager<Jedis> {

    
/**
     * active, attributes 

     */
    
public static final String NS_ACTIVE "sessoins:active";
    
public static final String NS_ATTRS "sessoins:attrs";
    
public static final String NS_TYPE "type";
    
public static final String REDIS_SEPS ":";
    
/**
     * 
标识active, 默认的session生命周期
     */
    
public static final String INFO_ACTIVE "true";
    
public static final int SESSION_ACTIVE_INTERVAL 60 60 1000;

    
/**
     * 
直接存在redis的数据类型
     */
    
public static final Class[] WRAPPER_AND_STRING_CLASSES new Class[]{
            Boolean.
class, Byte.class, Short.class, Character.class,
            Integer.
class, Long.class, Float.class, Double.class, String.class
    
};

    
// sessionId
    
private String sessionId;

    
private RedisSessionManager(String sessionId) {
        
this.sessionId = sessionId;
    }

    
/**
     * 
根据给定的sessoinId, 获取一个sessionManager
     *
     * @param 
sessionId sessoinId
     * @param 
jedis     redis连接
     * @return
     
@author Jerry.X.He
     */
    
public static SessionManager<Jedis> getSessionManager(String sessionId, Jedis jedis) {
        
if (Tools.isEmpty(sessionId) || (jedis == null) )  {
            
return RedisDummySessionManager.getSesssionManager(sessionId, jedis);
        }

        String activeKey = activeKey(sessionId);
        
boolean alive = jedis.exists(activeKey);
        
if (!alive) {
            
return RedisDummySessionManager.getSesssionManager(sessionId, jedis);
        }
        
return new RedisSessionManager(sessionId);
    }

    
/**
     * 
根据给定的sessoinId, 注册session
     *
     * @param 
sessionId sessoinId
     * @return
     
@author Jerry.X.He
     */
    
public static void activeSessionId(String sessionId, Jedis jedis) {
        
if (Tools.isEmpty(sessionId) || (jedis == null)) {
            
return;
        }

        String activeKey = activeKey(sessionId);
        jedis.set(activeKey, 
INFO_ACTIVE);
        jedis.expire(activeKey, 
SESSION_ACTIVE_INTERVAL);
    }

    
@Override
    
public void setAttribute(String key, Object val, Jedis jedis) {
        
if (Tools.isEmpty(key) || (val == null) || (jedis == null) ) {
            
return;
        }

        Class clazz = val.getClass();
        String clazzName = clazz.getName();
        String attrTypeKey = attrTypeKey(key);
        String attrKey = attrKey(
sessionId);

        String valStr = 
null;
        
if (clazz.isPrimitive() || (Tools.contains(WRAPPER_AND_STRING_CLASSES, clazz))) {
            valStr = String.valueOf(val);
        } 
else {
            valStr = JSONObject.fromObject(val).toString();
        }

        jedis.hset(attrKey, attrTypeKey, clazzName);
        jedis.hset(attrKey, key, valStr);
        jedis.expire(attrKey, 
SESSION_ACTIVE_INTERVAL);
    }

    
@Override
    
public Object getAttribute(String key, Jedis jedis) {
        
if (Tools.isEmpty(key) || (jedis == null)) {
            
return null;
        }

        String attrTypeKey = attrTypeKey(key);
        String attrKey = attrKey(
sessionId);
        String attrType = jedis.hget(attrKey, attrTypeKey);
        String attrVal = jedis.hget(attrKey, key);

        
if (Tools.isEmpty(attrType) || Tools.isEmpty(attrVal)) {
            
return null;
        }

        Class clazz = 
null;
        
try {
            clazz = Class.forName(attrType);
        } 
catch (ClassNotFoundException cnfe) {
            
return null;
        }

        
if (clazz.isPrimitive() || (Tools.contains(WRAPPER_AND_STRING_CLASSES, clazz))) {
            
return String.valueOf(attrVal);
        }
        Object result = 
null;
        
if (!clazz.isArray()) {
            result = JSONObject.toBean(JSONObject.fromObject(attrVal), clazz);
        } 
else {
            result = JSONArray.toArray(JSONArray.fromObject(attrVal), clazz);
        }
        
return result;
    }

    
@Override
    
public void removeAttribute(String key, Jedis jedis) {
        
if (Tools.isEmpty(key) || (jedis == null)) {
            
return;
        }

        String attrTypeKey = attrTypeKey(key);
        String attrKey = attrKey(
sessionId);
        jedis.hdel(attrKey, attrTypeKey, attrKey);
    }


    
// ----------------------------------------------------------- assist methods -----------------------------------------------------------


    /**
     * 
获取attrs区间的key
     *
     * @param 
sid sessionId
     * @return java.lang.String
     * @author Jerry.X.He
     * @since 2017/1/13 15:06
     */
    
private static String activeKey(String sid) {
        
return NS_ACTIVE REDIS_SEPS + sid;
    }

    
/**
     * 
获取attrs区间的key
     *
     * @param 
sid sessionId
     * @return java.lang.String
     * @author Jerry.X.He
     * @since 2017/1/13 15:06
     */
    
private static String attrKey(String sid) {
        
return NS_ATTRS REDIS_SEPS + sid;
    }

    
/**
     * 
获取attrs区间的key所属的type
     *
     * @return java.lang.String
     * @author Jerry.X.He
     * @since 2017/1/13 15:22
     */
    
private static String attrTypeKey(String key) {
        
return key + "_" NS_TYPE;
    }

}

 


使用截图 







  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值