什么是redis:redis是一个key-value存储系统。和Memcached类似,它支持存储的value类型相对更多,包括string(字符串)、list(链表)、set(集合)、zset(sorted set –有序集合)和hash(哈希类型)。这些数据类型都支持push/pop、add/remove及取交集并集和差集及更丰富的操作,而且这些操作都是原子性的。在此基础上,redis支持各种不同方式的排序。与memcached一样,为了保证效率,数据都是缓存在内存中。区别的是redis会周期性的把更新的数据写入磁盘或者把修改操作写入追加的记录文件,并且在此基础上实现了master-slave(主从)同步。(我也是百度的,个人理解reids就是个比较轻量级的key——value模式的数据库,这个数据库的存储性能很好,可以用来代替缓存实现的很多功能。而且这个redis数据库是第三方独立的服务,可以用在负载均衡情况下多个服务器,多个web容器之间公用数据的缓存。) 要使用reids,首先可以到官网reids的jar包和redis。 然后把redis的jar包导入到项目中。 ![](http://img.5iqiqu.com/images7/17/1704724593ad56ce733d587c3908ce9d.jpg) 我用的版本是2.1.0. 系统是32位的,所以我解压了32位的redis服务。 ![](http://img.5iqiqu.com/images7/39/397518df73568433cdda87b3f0ca980d.jpg)
打开以后使用里面的redis-servier。exe来启动redis服务。启动后的结果如下图所示 ![](http://img.5iqiqu.com/images7/9d/9d46f212896ad9ee1e22599531b41900.jpg)
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 | package org.calonlan.security.component; import java.util.Iterator; import java.util.Set; import org.springframework.beans.factory.annotation.Value; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; /** * @author Administrator * redismanager主要用来给用户提供一个设计完备的,通过jedis的jar包来管理redis内存数据库的各种方法 / public class RedisManager { // ip和port属性都定义在了properties文件中,这里通过spring的注解方式来直接使用 @Value("${redis.ip}") private String host; @Value("${redis.port}") private int port; // 设置为0的话就是永远都不会过期 private int expire = 0; // 定义一个管理池,所有的redisManager共同使用。 private static JedisPool jedisPool = null; public RedisManager() { } /* * * 初始化方法,在这个方法中通过host和port来初始化jedispool。 * * / public void init() { if (null == host || 0 == port) { System.out.println("请初始化redis配置文件"); throw new NullPointerException("找不到redis配置"); } if (jedisPool == null) { jedisPool = new JedisPool(new JedisPoolConfig(), host, port); } } /* * get value from redis * * @param key * @return / public byte[] get(byte[] key) { byte[] value = null; Jedis jedis = jedisPool.getResource(); try { value = jedis.get(key); } finally { jedisPool.returnResource(jedis); } return value; } /* * get value from redis * * @param key * @return / public String get(String key) { String value = null; Jedis jedis = jedisPool.getResource(); try { value = jedis.get(key); } finally { jedisPool.returnResource(jedis); } return value; } /* * set * * @param key * @param value * @return / public byte[] set(byte[] key, byte[] value) { Jedis jedis = jedisPool.getResource(); try { jedis.set(key, value); if (this.expire != 0) { jedis.expire(key, this.expire); } } finally { jedisPool.returnResource(jedis); } return value; } /* * set * * @param key * @param value * @return / public String set(String key, String value) { Jedis jedis = jedisPool.getResource(); try { jedis.set(key, value); if (this.expire != 0) { jedis.expire(key, this.expire); } } finally { jedisPool.returnResource(jedis); } return value; } /* * set * * @param key * @param value * @param expire * @return / public byte[] set(byte[] key, byte[] value, int expire) { Jedis jedis = jedisPool.getResource(); try { jedis.set(key, value); if (expire != 0) { jedis.expire(key, expire); } } finally { jedisPool.returnResource(jedis); } return value; } /* * set * * @param key * @param value * @param expire * @return / public String set(String key, String value, int expire) { Jedis jedis = jedisPool.getResource(); try { jedis.set(key, value); if (expire != 0) { jedis.expire(key, expire); } } finally { jedisPool.returnResource(jedis); } return value; } /* * del * * @param key / public void del(byte[] key) { Jedis jedis = jedisPool.getResource(); try { jedis.del(key); } finally { jedisPool.returnResource(jedis); } } /* * del * * @param key / public void del(String key) { Jedis jedis = jedisPool.getResource(); try { jedis.del(key); } finally { jedisPool.returnResource(jedis); } } /* * flush / public void flushDB() { Jedis jedis = jedisPool.getResource(); try { jedis.flushDB(); } finally { jedisPool.returnResource(jedis); } } /* * size / public Long dbSize() { Long dbSize = 0L; Jedis jedis = jedisPool.getResource(); try { dbSize = jedis.dbSize(); } finally { jedisPool.returnResource(jedis); } return dbSize; } /* * keys * * @param regex * @return */ public Set<byte[]> keys(String pattern) { Set<byte[]> keys = null; Jedis jedis = jedisPool.getResource(); try { keys = jedis.keys(pattern.getBytes()); } finally { jedisPool.returnResource(jedis); } return keys; } public void dels(String pattern) { Set<byte[]> keys = null; Jedis jedis = jedisPool.getResource(); try { keys = jedis.keys(pattern.getBytes()); Iterator<byte[]> ito = keys.iterator(); while (ito.hasNext()) { jedis.del(ito.next()); } } finally { jedisPool.returnResource(jedis); } } public String getHost() { return host; } public void setHost(String host) { this.host = host; } public int getPort() { return port; } public void setPort(int port) { this.port = port; } public int getExpire() { return expire; } public void setExpire(int expire) { this.expire = expire; } } </byte[]></byte[]></byte[]></byte[]> |
1 | 1 |
这里的redisManager是通过spring来进行管理的,所以直接使用了@value来读取properties文件中的属性。properties文件的内容如下:
?
1 2 | <span style="white-space:pre"> </span>redis.ip=127.0.0.1 <span style="white-space:pre"> </span> redis.port=6379 |
1 | 1 |
ip定义为本机的ip,端口是redis默认的6379端口。
?
1 2 3 4 5 6 7 8 | <bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" id="propertyConfigurer"> <property name="locations"> <list> <value>classpath:/config/jdbc.properties</value> <value>classpath:/config/redis.properties</value> </list> </property> </bean> |
1 | 1 |
在spring中就是在这个地方把reids服务的配置文件redis.properties文件加载到spring中管理的。
这样redis服务就集成到了项目中,具体的使用,通过对shiro默认缓存和session数据的缓存的保存过程来展示。
项目中遇到的问题是这样的,在同时使用一个机器使用多个web容器或者多个机器同时来为一个项目进行负载均衡时,shiro的默认缓存和session数据无法在多个web容器或者多个机器之间进行同步。为了达到多web容器或多机器负载均衡的目的,我们修改了shiro的默认session管理器和缓存管理器来使shiro通过redis来管理session和缓存。这样多个web容器或机器之间的数据就可以互通共用了。 首先是shiro的配置文件,我用的是spring集成的方式。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 | <beans default-lazy-init="false" xmlns="http://www.springframework.org/schema/beans" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemalocation=" http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!– 缓存管理器 –> <bean class="org.calonlan.security.spring.SpringCacheManagerWrapper" id="cacheManager"> <property name="cacheManager" ref="springCacheManager"> </property></bean> <!– 凭证匹配器 –> <bean class="org.calonlan.security.credentials.RetryLimitHashedCredentialsMatcher" id="credentialsMatcher"> <constructor-arg ref="cacheManager"> <property name="hashAlgorithmName" value="md5"> <property name="hashIterations" value="2"> <property name="storedCredentialsHexEncoded" value="true"> </property></property></property></constructor-arg></bean> <!– Realm实现 –> <bean class="org.calonlan.security.realm.UserRealm" id="userRealm"> <property name="credentialsMatcher" ref="credentialsMatcher"> <property name="cachingEnabled" value="true"> <!–<property name="authenticationCachingEnabled" value="true"/> –> <!–<property name="authenticationCacheName" value="authenticationCache"/> –> <!–<property name="authorizationCachingEnabled" value="true"/> –> <!–<property name="authorizationCacheName" value="authorizationCache"/> –> </property></property></bean> <!– 会话ID生成器 –> <bean class="org.apache.shiro.session.mgt.eis.JavaUuidSessionIdGenerator" id="sessionIdGenerator"> <!– 会话Cookie模板 –> <bean class="org.apache.shiro.web.servlet.SimpleCookie" id="sessionIdCookie"> <constructor-arg value="sid"> <property name="httpOnly" value="true"> <property name="maxAge" value="-1"> </property></property></constructor-arg></bean> <bean class="org.apache.shiro.web.servlet.SimpleCookie" id="rememberMeCookie"> <constructor-arg value="rememberMe"> <property name="httpOnly" value="true"> <property name="maxAge" value="2592000"><!– 30天 –> </property></property></constructor-arg></bean> <!– rememberMe管理器 –> <bean class="org.apache.shiro.web.mgt.CookieRememberMeManager" id="rememberMeManager"> <!– rememberMe cookie加密的密钥 建议每个项目都不一样 默认AES算法 密钥长度(128 256 512 位) –> <property name="cipherKey" value="#{T(org.apache.shiro.codec.Base64).decode('4AvVhmFLUs0KTA3Kprsdag==')}"> <property name="cookie" ref="rememberMeCookie"> </property></property></bean> <!– 会话DAO –> <bean class="org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO" id="sessionDAO"> <property name="activeSessionsCacheName" value="shiro-activeSessionCache"> <property name="sessionIdGenerator" ref="sessionIdGenerator"> </property></property></bean> <!– 会话验证调度器 –> <bean class="org.apache.shiro.session.mgt.quartz.QuartzSessionValidationScheduler" id="sessionValidationScheduler"> <property name="sessionValidationInterval" value="1800000"> <property name="sessionManager" ref="sessionManager"> </property></property></bean> <!– 会话管理器 –> <bean class="org.apache.shiro.web.session.mgt.DefaultWebSessionManager" id="sessionManager"> <property name="globalSessionTimeout" value="1800000"> <property name="deleteInvalidSessions" value="true"> <property name="sessionValidationSchedulerEnabled" value="true"> <property name="sessionValidationScheduler" ref="sessionValidationScheduler"> <property name="sessionIdCookieEnabled" property="" ref="<span style=" value="true"> <property name="sessionIdCookie" ref="sessionIdCookie"> </property></property></property></property></property></property></bean> <span style="color:#ff0000;"><bean class="org.calonlan.security.component.CustomShiroSessionDao" id="customShiroSessionDAO"> <property name="shiroSessionRepository" ref="jedisShiroSessionRepository">//自己定义的sessiondao </property></bean></span> <span style="color:#ff0000;"> <bean class="org.calonlan.security.component.JedisShiroSessionRepository" id="jedisShiroSessionRepository"> <property name="redisManager" ref="redisManager"></property> </bean></span> <span style="color:#ff0000;"><bean class="org.calonlan.security.component.RedisManager" id="redisManager"></bean>//注册上面实现的redisManager到spring中</span> <span style="background-color: rgb(255, 0, 0);"><bean class="org.calonlan.security.component.JedisShiroCacheManager" id="jedisShiroCacheManager"> <property name="redisManager" ref="redisManager"></property> </bean></span><span style="background-color: rgb(255, 255, 255);"> </span> <span style="color:#ff0000;"> <bean class="org.calonlan.security.component.CustomShiroCacheManager" id="customShiroCacheManager"> <property name="shrioCacheManager" ref="jedisShiroCacheManager"></property> </bean></span> <!– 安全管理器 –> <bean class="org.apache.shiro.web.mgt.DefaultWebSecurityManager" id="securityManager"> <property name="realm" ref="userRealm"> <property name="sessionManager" ref="sessionManager"> <property name="rememberMeManager" property="" ref="rememberMeManager"> </property></property></property></bean> <!– 相当于调用SecurityUtils.setSecurityManager(securityManager) –> <bean class="org.springframework.beans.factory.config.MethodInvokingFactoryBean"> <property name="staticMethod" value="org.apache.shiro.SecurityUtils.setSecurityManager"> <property name="arguments" ref="securityManager"> </property></property></bean> <!– 基于Form表单的身份验证过滤器 –> <bean class="org.apache.shiro.web.filter.authc.FormAuthenticationFilter" id="formAuthenticationFilter"> <property name="usernameParam" value="username"> <property name="passwordParam" value="password"> <property name="rememberMeParam" value="rememberMe"> <property name="loginUrl" value="/login"> </property></property></property></property></bean> <bean class="org.calonlan.security.web.shiro.filter.SysUserFilter" id="sysUserFilter"> <!– Shiro的Web过滤器 –> <bean class="org.apache.shiro.spring.web.ShiroFilterFactoryBean" id="shiroFilter"> <property name="securityManager" ref="securityManager"> <!– 逻辑上正确,不起作用 –> <property name="loginUrl" value="/login"> <property name="successUrl" value="/admin/index"> <property name="filters"> util:map <entry key="authc" value-ref="formAuthenticationFilter"> <entry key="sysUser" value-ref="sysUserFilter"> </entry></entry></util:map> </property> <property name="filterChainDefinitions"> <value> /img/** =anon /ueditor/jsp/upload/** =anon /login = authc /authenticated = authc /css/** = anon /common/** = anon /js/** = anon /admin/** = user,sysUser //*=anon </value> </property> </property></property></property></bean> <!– Shiro生命周期处理器 –> <bean class="org.apache.shiro.spring.LifecycleBeanPostProcessor" id="lifecycleBeanPostProcessor"> </bean></bean></bean></beans> |
1 | 1 |
主要看上图的红色部分:其中customShiroSessionDAO、jedisShiroSessionRepository用来处理session;customShiroCacheManager、jedisShiroCacheManager用来处理缓存。
他们的源代码如下:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 | package org.calonlan.security.component; import java.io.Serializable; import java.util.Collection; import org.apache.shiro.session.Session; import org.apache.shiro.session.UnknownSessionException; import org.apache.shiro.session.mgt.eis.AbstractSessionDAO; public class CustomShiroSessionDao extends AbstractSessionDAO { private ShiroSessionRepository shiroSessionRepository; public ShiroSessionRepository getShiroSessionRepository() { return shiroSessionRepository; } public void setShiroSessionRepository( ShiroSessionRepository shiroSessionRepository) { this.shiroSessionRepository = shiroSessionRepository; } @Override public void delete(Session session) { if (session == null) { System.out.println("错误"); return; } Serializable id = session.getId(); if (id != null) getShiroSessionRepository().deleteSession(id); } @Override public Collection<session> getActiveSessions() { return getShiroSessionRepository().getAllSessions(); } @Override public void update(Session session) throws UnknownSessionException { getShiroSessionRepository().saveSession(session); } @Override protected Serializable doCreate(Session session) { Serializable sessionId = this.generateSessionId(session); this.assignSessionId(session, sessionId); getShiroSessionRepository().saveSession(session); return sessionId; } @Override protected Session doReadSession(Serializable sessionId) { return getShiroSessionRepository().getSession(sessionId); } } </session> |
1 | 1 |
这里我们是继承了shiro的AbstractSessionDAO,然后仿照shiro的模式,给他一个shiroSessionRepository,来进行详细的session存储操作。
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | package org.calonlan.security.component; import java.io.Serializable; import java.util.Collection; import org.apache.shiro.session.Session; public interface ShiroSessionRepository { void saveSession(Session session); void deleteSession(Serializable sessionId); Session getSession(Serializable sessionId); Collection<session> getAllSessions(); }</session> |
1 | 1 |
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | package org.calonlan.security.component; import java.io.Serializable; import java.util.Collection; import java.util.HashSet; import java.util.Set; import org.apache.shiro.session.Session; public class JedisShiroSessionRepository implements ShiroSessionRepository { /** * * redis session key 前缀 * * / private final String REDIS_SHIRO_SESSION = "shiro-session"; private RedisManager redisManager; @Override public void saveSession(Session session) { redisManager.init(); if (session == null || session.getId() == null) { System.out.println("session 或者 session ID 为空"); } byte[] key = SerializeUtils.serialize(getRedisSessionKey(session .getId())); byte[] value = SerializeUtils.serialize(session); Long timeOut = session.getTimeout() / 1000; redisManager.set(key, value, Integer.parseInt(timeOut.toString())); } @Override public void deleteSession(Serializable sessionId) { redisManager.init(); if (sessionId == null) { System.out.println("id为空"); } redisManager.del(SerializeUtils .serialize(getRedisSessionKey(sessionId))); } @Override public Session getSession(Serializable sessionId) { redisManager.init(); if (null == sessionId) { System.out.println("id为空"); return null; } Session session = null; byte[] value = redisManager.get(SerializeUtils .serialize(getRedisSessionKey(sessionId))); if (null == value) return null; session = (Session) SerializeUtils.deserialize(value); return session; } @Override public Collection<session> getAllSessions() { redisManager.init(); Set<session> sessions = new HashSet<session>(); Set<byte[]> byteKeys = redisManager .keys(this.REDIS_SHIRO_SESSION + ""); if (byteKeys != null && byteKeys.size() > 0) { for (byte[] bs : byteKeys) { Session s = (Session) SerializeUtils.deserialize(redisManager .get(bs)); sessions.add(s); } } return sessions; } /** * 获取redis中的session key * * @param sessionId * @return */ private String getRedisSessionKey(Serializable sessionId) { return this.REDIS_SHIRO_SESSION + sessionId; } public RedisManager getRedisManager() { return redisManager; } public void setRedisManager(RedisManager redisManager) { this.redisManager = redisManager; } public JedisShiroSessionRepository() { } // public static void main(String[] args) { // Jedis jj = new Jedis("localhost"); // //jj.set("key2", "232323231========="); // String ss = jj.get("key1"); // System.out.println(jj.get("key2")); // System.out.println(ss); // } } </byte[]></session></session></session> |
1 | 1 |
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | package org.calonlan.security.component; import org.apache.shiro.cache.Cache; import org.apache.shiro.cache.CacheException; import org.apache.shiro.cache.CacheManager; import org.apache.shiro.util.Destroyable; public class CustomShiroCacheManager implements CacheManager, Destroyable { private ShiroCacheManager shrioCacheManager; public ShiroCacheManager getShrioCacheManager() { return shrioCacheManager; } public void setShrioCacheManager(ShiroCacheManager shrioCacheManager) { this.shrioCacheManager = shrioCacheManager; } @Override public void destroy() throws Exception { getShrioCacheManager().destroy(); } @Override public <k, v=""> Cache<k, v=""> getCache(String name) throws CacheException { return getShrioCacheManager().getCache(name); } } </k,></k,> |
1 | 1 |
?
1 2 3 4 5 6 7 8 9 10 | package org.calonlan.security.component; import org.apache.shiro.cache.Cache; public interface ShiroCacheManager { <k, v=""> Cache<k, v=""> getCache(String name); void destroy(); } </k,></k,> |
1 | 1 |
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | package org.calonlan.security.component; import org.apache.shiro.cache.Cache; public class JedisShiroCacheManager implements ShiroCacheManager { private RedisManager redisManager; public RedisManager getRedisManager() { return redisManager; } public void setRedisManager(RedisManager redisManager) { this.redisManager = redisManager; } @Override public <k, v=""> Cache<k, v=""> getCache(String name) { return new JedisShiroCache<k, v="">(redisManager, name); } @Override public void destroy() { redisManager.init(); redisManager.flushDB(); } } </k,></k,></k,> |
1 | 1 |
具体的使用就如如上代码所示,为什么要弄一个什么ShiroCacheManager和ShiroSessionRepository接口呢,我想各位大侠也能知道的。有了这个两个接口,我们就可以通过这个两个接口来实现更多形式的shiro的session和缓存的管理了。
在很多地方使用到了SerializeUtils,它的作用就是把对象转化为byte数组,或把byte数组转化为对象。源代码如下:
?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | package org.calonlan.security.component; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; public class SerializeUtils { public static byte[] serialize(Object o) { ByteArrayOutputStream out = new ByteArrayOutputStream(); try { ObjectOutputStream outo = new ObjectOutputStream(out); outo.writeObject(o); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } return out.toByteArray(); } public static Object deserialize(byte[] b) { ObjectInputStream oin; try { oin = new ObjectInputStream(new ByteArrayInputStream(b)); try { return oin.readObject(); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); return null; } } } |
1 | 1 |
然后项目的运行结果如下: ![](http://img.5iqiqu.com/images7/0c/0ce34920d624c66f7cbdf2cc00d948a1.jpg)
从图中可以看到,我登录后,session信息已经保存到了redis数据库中。多个tomcat做负载均衡的测试结果也很良好,但是我这个笔记本没有安装那种环境,所以无法测试。这都是个人一点小东西,各位大神勿喷。