这个需求这样的, 我们做一个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;
}
}
使用截图
完