由代码可以看到,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;
}
}
分享到:
相关推荐
在Java编程环境中,将Excel数据导入到数据库以及将数据库数据导出到Excel是常见的数据处理需求。本篇文章将深入探讨如何使用Java实现这两个功能,主要涉及的技术栈包括Apache POI库用于操作Excel,以及JDBC(Java ...
本文将深入探讨如何使用Java来实现多个数据库之间的数据同步。 首先,我们需要理解数据同步的含义。数据同步是指在两个或多个数据库之间,当某个数据库中的数据发生改变时,这些变化能够被实时或者近实时地反映到...
本文将深入探讨如何使用Java编程语言实现从一个数据库中定时自动抽取数据并复制到另一个数据库,以达到数据库间的实时或近实时同步。 首先,我们需要了解基础概念。Java是一种广泛使用的面向对象的编程语言,具有...
数据库迁移是指将数据从一个数据库系统迁移到另一个数据库系统的过程,或者在同一系统中不同版本之间进行数据转移。这通常涉及到数据的抽取、转换和加载(ETL)过程,以及确保数据的一致性和完整性。 Java作为广泛...
exp 命令用于将 Oracle 数据库数据导出到文件中,而 imp 命令用于将数据从文件中导入到 Oracle 数据库中。这些命令可以在命令行中使用,例如,在 Windows 中,可以打开命令行窗口,输入 exp 用户名/密码@标识 file=d...
本项目关注的是如何使用Java来实现读取Microsoft Word文件,并将其中的数据上传到数据库,以此提升数据录入的效率。这一过程涉及到多个技术点,包括文件I/O、Word文档解析、数据库操作以及可能的数据转换。 首先,...
Java实现从excel中批量高效导入数据到数据库中,包括图片的导入存储,读取图片显示在jsp页面等,需要下载JspSmartUpload.jar和jxl.jar两个jar包,将两个包导入项目才能运行
在本文中,我们将深入探讨如何使用Java开发一个串口助手应用程序,该程序能接收来自串行端口的数据并将其解析后存储到MySQL数据库中。首先,我们需要了解串口通信的基本概念,然后学习Java如何处理串口输入,接着是...
Java 实现高效数据库插入数据 在 Java 程序中,实现高效的数据库插入数据是非常重要的。以下是相关的知识点: 使用 JDBC 连接数据库 在 Java 程序中,使用 JDBC(Java Database Connectivity)连接数据库是非常...
在Java编程中,将文件保存到数据库是一种常见的需求,特别是在处理图像、文档和其他非结构化数据时。这个过程涉及到将文件转换为二进制数据,然后将这些数据存储到数据库的特定字段中,通常是一个BLOB(Binary Large...
将本地硬盘中的文本数据读取到mysql的数据库表中。 1. 文件保存在本地目录下,按照固定的格式保存,每一行对应着数据库中的一条记录,属性用空格隔开。 2. 创建数据库表,字段需要和文本文件的数据逐列对应。 3. ...
在IT领域,它被广泛用于生成报告、发票、证书等,特别是在需要将数据动态地从数据库填充到预定义模板的情况。在这个场景中,"java iText 实现从数据库中导出数据到已有的PDF模板"是一个常见的需求,它涉及到多个关键...
在Java中,我们可以使用文件系统、内存数据结构或关系型数据库管理系统(如SQLite)作为数据存储。 2. **查询解析器**:负责接收用户输入的SQL语句并进行解析,将其转化为可执行的操作。 3. **执行引擎**:执行...
在IT行业中,数据库同步是一个常见的需求,特别是在分布式系统或者高可用架构中,为了保证数据的一致性和完整性,通常需要将一个数据库(主库)的数据实时或定时地复制到另一个数据库(从库)。在这个场景中,Java...
1、java解析读取excel文件中的数据,并写入数据库。 2、java读取数据库数据,并导出为excel文件。 3、README.md中有详细的操作步骤示例。 使用说明: 1. 先使用postman导入:other/excel相关.postman_collection....
在IT行业中,数据的导入与导出是常见的操作...总的来说,通过Java将数据库导入CSV程序,我们可以实现数据的高效迁移和共享,同时利用CSV的灵活性和通用性。对于Java开发者来说,掌握这样的技能对日常开发工作大有裨益。
Java建立数据库连接并实现数据库查询,初学者通过本Java源代码,了解如何加载驱动器,获取连接,定义SQL查询语句,获取Statement对象,执行查询、遍历ResultSet、获取数据、在控制台输出数据,关闭连接等。
在本文中,我们将深入探讨如何使用Java实现在本地读取图片并将其存储到数据库中,之后再通过HTML页面显示这些图片。这个过程涉及到的主要技术包括Java编程、数据库操作(特别是MySQL)以及前后端交互。 首先,我们...
- 当检测到数据库有新数据时,后端通过已经建立的WebSocket连接,将更新的消息推送给前端。 - 前端页面接收到WebSocket消息后,刷新显示最新的数据库内容,无需手动刷新整个页面。 总结来说,这个项目通过...
java连接oracle数据库,并将从数据库中读取到得内容存放到txt文件中