jave如何实现将上海宝付数据库数据存到内存

需求:

在做 session 共享的时候,需要将 session 持久化的数据库中,每次有请求时候会从数据库查询出 session 数据,下面看一下 session 类。

我用的是 Shiro 的 SimpleSession ,看一下 SimpleSession 实现:

// IntelliJ API Decompiler stub source generated from a class file

// Implementation of methods is not available

package org.apache.shiro.session.mgt;

public class SimpleSession implements org.apache.shiro.session.mgt.ValidatingSession, java.io.Serializable {

private static final long serialVersionUID = -7125642695178165650L;

private static final transient org.slf4j.Logger log;

protected static final long MILLIS_PER_SECOND = 1000L;

protected static final long MILLIS_PER_MINUTE = 60000L;

protected static final long MILLIS_PER_HOUR = 3600000L;

static int bitIndexCounter;

private static final int ID_BIT_MASK;

private static final int START_TIMESTAMP_BIT_MASK;

private static final int STOP_TIMESTAMP_BIT_MASK;

private static final int LAST_ACCESS_TIME_BIT_MASK;

private static final int TIMEOUT_BIT_MASK;

private static final int EXPIRED_BIT_MASK;

private static final int HOST_BIT_MASK;

private static final int ATTRIBUTES_BIT_MASK;

private transient java.io.Serializable id;

private transient java.util.Date startTimestamp;

private transient java.util.Date stopTimestamp;

private transient java.util.Date lastAccessTime;

private transient long timeout;

private transient boolean expired;

private transient java.lang.String host;

private transient java.util.Map<java.lang.Object,java.lang.Object> attributes;

public SimpleSession() { / compiled code / }

public SimpleSession(java.lang.String host) { / compiled code / }

public java.io.Serializable getId() { / compiled code / }

public void setId(java.io.Serializable id) { / compiled code / }

public java.util.Date getStartTimestamp() { / compiled code / }

public void setStartTimestamp(java.util.Date startTimestamp) { / compiled code / }

public java.util.Date getStopTimestamp() { / compiled code / }

public void setStopTimestamp(java.util.Date stopTimestamp) { / compiled code / }

public java.util.Date getLastAccessTime() { / compiled code / }

public void setLastAccessTime(java.util.Date lastAccessTime) { / compiled code / }

public boolean isExpired() { / compiled code / }

public void setExpired(boolean expired) { / compiled code / }

public long getTimeout() { / compiled code / }

public void setTimeout(long timeout) { / compiled code / }

public java.lang.String getHost() { / compiled code / }

public void setHost(java.lang.String host) { / compiled code / }

public java.util.Map<java.lang.Object,java.lang.Object> getAttributes() { / compiled code / }

public void setAttributes(java.util.Map<java.lang.Object,java.lang.Object> attributes) { / compiled code / }

public void touch() { / compiled code / }

public void stop() { / compiled code / }

protected boolean isStopped() { / compiled code / }

protected void expire() { / compiled code / }

public boolean isValid() { / compiled code / }

protected boolean isTimedOut() { / compiled code / }

public void validate() throws org.apache.shiro.session.InvalidSessionException { / compiled code / }

private java.util.Map<java.lang.Object,java.lang.Object> getAttributesLazy() { / compiled code / }

public java.util.Collection<java.lang.Object> getAttributeKeys() throws org.apache.shiro.session.InvalidSessionException { / compiled code / }

public java.lang.Object getAttribute(java.lang.Object key) { / compiled code / }

public void setAttribute(java.lang.Object key, java.lang.Object value) { / compiled code / }

public java.lang.Object removeAttribute(java.lang.Object key) { / compiled code / }

public boolean equals(java.lang.Object obj) { / compiled code / }

protected boolean onEquals(org.apache.shiro.session.mgt.SimpleSession ss) { / compiled code / }

public int hashCode() { / compiled code / }

public java.lang.String toString() { / compiled code / }

private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException { / compiled code / }

private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, java.lang.ClassNotFoundException { / compiled code / }

private short getAlteredFieldsBitMask() { / compiled code / }

private static boolean isFieldPresent(short bitMask, int fieldBitMask) { / compiled code / }

}

由代码可以看到,SimpleSession 实现了和 Serializable,下面再看一下 ValidatingSession 接口

// IntelliJ API Decompiler stub source generated from a class file

// Implementation of methods is not available

package org.apache.shiro.session.mgt;

public interface ValidatingSession extends org.apache.shiro.session.Session {

boolean isValid();

void validate() throws org.apache.shiro.session.InvalidSessionException;

}

可以看到,ValidatingSession 接口继承了 org.apache.shiro.session.Session 接口,下面再看看 org.apache.shiro.session.Session 接口

// IntelliJ API Decompiler stub source generated from a class file

// Implementation of methods is not available

package org.apache.shiro.session;

public interface Session {

java.io.Serializable getId();

java.util.Date getStartTimestamp();

java.util.Date getLastAccessTime();

long getTimeout() throws org.apache.shiro.session.InvalidSessionException;

void setTimeout(long l) throws org.apache.shiro.session.InvalidSessionException;

java.lang.String getHost();

void touch() throws org.apache.shiro.session.InvalidSessionException;

void stop() throws org.apache.shiro.session.InvalidSessionException;

java.util.Collection<java.lang.Object> getAttributeKeys() throws org.apache.shiro.session.InvalidSessionException;

java.lang.Object getAttribute(java.lang.Object o) throws org.apache.shiro.session.InvalidSessionException;

void setAttribute(java.lang.Object o, java.lang.Object o1) throws org.apache.shiro.session.InvalidSessionException;

java.lang.Object removeAttribute(java.lang.Object o) throws org.apache.shiro.session.InvalidSessionException;

}

有上述代码可以看到,SimpleSession 对象是一个比较复杂的对象,既有很多个属性,又有多个复杂方法,如果直接使用Jackson工具转化为 json 格式字符串存入数据库,最终是无法解析出来的

我的解决方案是:

存储方案
1.1 将对象序列化到内存中,并生成一个字节数据
1.2 将1.1中得到的字节数组转化为 base64 位的字符串
1.3 将1.2中得到的字符串存入数据库即可
读取方案
2.1 从数据库中读取 base64 加密后的字符串
2.2 将2.1中的加密字符串解密成字节数组
2.3 将2.3中的字节数组反序列化
具体实现

我这里借助 org.apache.commons.lang3.SerializationUtils 工具类来实现,序列化功能代码如下:

package com.lixiaohao.test.springshiro.util;

import org.apache.commons.lang3.SerializationUtils;

import org.apache.shiro.codec.Base64;

import org.apache.shiro.session.Session;

import java.io.Serializable;

/**

  • @program: shiroTest

  • @description:

  • @author: xiaohao.li

  • @create: 2018-07-30 14:55

**/

public class SerializeUtils extends SerializationUtils {

public static String serializeToString(Serializable obj) {

try {

byte[] value = serialize(obj);

return Base64.encodeToString(value);

} catch (Exception e) {

throw new RuntimeException("serialize session error", e);

}

}

public static Session deserializeFromString(String base64) {

try {

byte[] objectData = Base64.decode(base64);

return deserialize(objectData);

} catch (Exception e) {

throw new RuntimeException("deserialize session error", e);

}

}

}

session管理功能如下:

package com.lixiaohao.test.springshiro.session;

import com.lixiaohao.test.springshiro.dao.SessionModelDao;

import com.lixiaohao.test.springshiro.dao.UserDao;

import com.lixiaohao.test.springshiro.model.SessionModel;

import com.lixiaohao.test.springshiro.model.User;

import com.lixiaohao.test.springshiro.util.JsonUtils;

import com.lixiaohao.test.springshiro.util.SerializeUtils;

import org.apache.shiro.session.Session;

import org.apache.shiro.session.mgt.SimpleSession;

import org.apache.shiro.session.mgt.eis.CachingSessionDAO;

import org.springframework.beans.factory.annotation.Autowired;

import java.io.Serializable;

import com.lixiaohao.test.springshiro.util.StringUtils;

/**

  • @program: shiroTest

  • @description:

  • @author: xiaohao.li

  • @create: 2018-07-26 12:40

**/

public class UserCacheSessionDao extends CachingSessionDAO{

private final String PRINCIPALS_SESSION_KEY = "org.apache.shiro.subject.support.DefaultSubjectContext_PRINCIPALS_SESSION_KEY";

@Autowired

private SessionModelDao sessionModelDao;

@Autowired

private UserDao userDao;

protected void doUpdate(Session session) {

}

protected void doDelete(Session session) {

if ( session == null ) {

throw new NullPointerException(" session argument can not be null ");

}

String sessionId = (String)session.getId();

if ( StringUtils.isEmpty(sessionId) ) {

throw new NullPointerException(" property sessionId can not be null in session argument ");

}

sessionModelDao.delete(sessionId);

}

protected Serializable doCreate(Session session) {

if ( session == null ) {

throw new NullPointerException(" session argument can not be null ");

}

String sessionId = (String) generateSessionId(session);

assignSessionId(session,sessionId);

storeSession(session);

return sessionId;

}

private void storeSession(Session session){

String sessionId = (String) session.getId();

SessionModel sessionModel = new SessionModel();

sessionModel.setSessionId(sessionId);

sessionModel.setStatus(1);

//将对象序列化

String sessionStr = SerializeUtils.serializeToString((SimpleSession)session);

sessionModel.setSessionStr(sessionStr);

Object principals = session.getAttribute(PRINCIPALS_SESSION_KEY);

if ( principals != null ) {

User user = userDao.findByUserName((String) principals);

sessionModel.setValue(JsonUtils.objectToJson(user));

}

System.out.println("保存session -------->> "+JsonUtils.objectToJson(sessionModel));

sessionModelDao.insert(sessionModel);

}

protected Session doReadSession(Serializable sessionId) {

if ( sessionId == null ) {

throw new NullPointerException(" sessionId argument can not be null. ");

}

String id = (String) sessionId;

SessionModel sessionMode = sessionModelDao.findBySessionId(id);

if ( sessionMode == null ) {

return null;

}

java.lang.String sessionStr = sessionMode.getSessionStr();

//反序列化对象

Session session = SerializeUtils.deserializeFromString(sessionStr);

return session;

}

}

猜你喜欢

转载自blog.51cto.com/14805651/2497238