由于一直在弄oa系统,涉及与公司的其它系统整合;
今天要弄的是用redis做同步登陆,即在oa里登陆成功后即可在其它系统实现一键登陆。
oa是用shiro登陆的,shiro里也提供了一个redis的同步session机制,不过在测试时发现,不能用,同一个请求都会产生不同的sessionid,应该是shiro底层问题,在读取sessionid时由于某些原因总是为空,于是就时不时产生一个新的sessionid,这样就没办法实现同步了,同步需要只使用一个sessionid.
既然不用shiro的,那么就要自己来实现,就得做个filter,拦截在系统的最前面,即在shiro的filter的前面,
这里是SSOFilter.
本来想存session到redis的,后来想到公司还有其它语言的系统,有.net的,这可能会对他们造成读取困难,那就直接以sessionid为key,userName为value存到redis里吧。
下面上源码吧!
RedisManager
package sy.sso; import java.util.Set; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig; import sy.action.InitAction; public class RedisManager { private final Logger logger = LoggerFactory.getLogger(this.getClass()); /*private String host = "172.16.6.3";*/ private String host = "127.0.0.1"; private int port = 6379; private String dbindex = "0"; private String password = "123456"; // 0 - never expire private int expire = 30; private int timeout = 2000; private JedisPool jedisPool = null; public RedisManager() { init(); } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getDbindex() { return dbindex; } public void setDbindex(String dbindex) { this.dbindex = dbindex; } /** * 初始化方法 */ public void init() { if (jedisPool == null) { //jedisPool = new JedisPool(new JedisPoolConfig(), host, port, timeout, password, Integer.parseInt(dbindex)); jedisPool = new JedisPool(new JedisPoolConfig(), host, port, timeout, null, Integer.parseInt(dbindex)); } } /** * get value from redis * * @param key * @return */ public byte[] get(byte[] key) { logger.debug("getkey:" + new String(key)); byte[] value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.get(key); } finally { jedisPool.returnResource(jedis); } return value; } /** * 返回指定hash的field数量 * * @param key * @return */ public Long hlen(String key) { Long value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.hlen(key); } finally { jedisPool.returnResource(jedis); } return value; } /** * 获取指定的hash field * * @param key * @return */ public String hget(String key, String value) { Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.hget(key, value); } finally { jedisPool.returnResource(jedis); } return value; } /** * 设置hash field为指定值,如果key不存在,则先创建 * * @param key * @return */ public Long hset(String key, String value1, String value2) { Long value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.hset(key, value1, value2); } finally { jedisPool.returnResource(jedis); } return value; } /** * 添加一个string元素到,key对应的set集合中,成功返回1,如果元素以及在集合中返回0,key对应的set不存在返回错误 * * @param key * @return */ public Long sadd(String key, String value1) { Long value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.sadd(key, value1); } finally { jedisPool.returnResource(jedis); } return value; } /** * 为key指定过期时间,单位是秒。返回1成功,0表示key已经设置过过期时间或者不存在 * * @param key * @return */ public Long expire(String key, int value1) { Long value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.expire(key, value1); } finally { jedisPool.returnResource(jedis); } return value; } /** * 判断member是否在set中 * * @param key * @return */ public Boolean sismember(String key, String value1) { Boolean value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.sismember(key, value1); } finally { jedisPool.returnResource(jedis); } return value; } /** * 从key对应set中移除给定元素,成功返回1,如果member在集合中不 * * @param key * @return */ public Long srem(String key, String value1) { Long value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.srem(key, value1); } 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.auth(password); 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.auth(password); 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.auth(password); jedis.del(key); } finally { jedisPool.returnResource(jedis); } } /** * flush */ public void flushDB() { Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); jedis.flushDB(); } finally { jedisPool.returnResource(jedis); } } /** * size */ public Long dbSize() { Long dbSize = 0L; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); 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 { jedis.auth(password); keys = jedis.keys(pattern.getBytes()); } finally { jedisPool.returnResource(jedis); } return keys; } 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; } public static void main(String[] args) { // Jedis jedis = new Jedis("192.168.126.89", 6379); // jedis.auth("123456"); RedisManager manager = new RedisManager(); manager.setHost("192.168.126.89"); manager.init(); for (int i = 0; i < 100000; i++) { // BoardItem item = new BoardItem(i+"", "clientId"+i, i, 8, 0); String item = i + "|" + "clientId" + i; manager.zadd("test", i, item); } // jedis.set("aa", "记录了"); // System.out.println(jedis.get("aa")); System.out.println(manager.zrevrange("test", 0, 100)); System.out.println(manager.zrange("test", 0, 100)); } /** * 有序SET 添加 * * @param key * @param score * @param member * @return */ public Long zadd(String key, double score, String member) { Long value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.zadd(key, score, member); } finally { jedisPool.returnResource(jedis); } return value; } public Long zrem(String key, String member) { Long value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.zrem(key, member); } finally { jedisPool.returnResource(jedis); } return value; } public Set<String> zrevrange(String key, long start, long end) { Set<String> value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.zrevrange(key, start, end); } finally { jedisPool.returnResource(jedis); } return value; } public Set<String> zrange(String key, long start, long end) { Set<String> value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.zrange(key, start, end); } finally { jedisPool.returnResource(jedis); } return value; } public Long zrank(String key, String member) { Long value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.zrank(key, member); } finally { jedisPool.returnResource(jedis); } return value; } public Long zrevrank(String key, String member) { Long value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.zrevrank(key, member); } finally { jedisPool.returnResource(jedis); } return value; } public Long zcard(String key) { Long value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.zcard(key); } finally { jedisPool.returnResource(jedis); } return value; } public Set<redis.clients.jedis.Tuple> zrangeWithScores(String key, long start, long end) { Set<redis.clients.jedis.Tuple> value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.zrangeWithScores(key, start, end); } finally { jedisPool.returnResource(jedis); } return value; } public Set<redis.clients.jedis.Tuple> zrevrangeWithScores(String key, long start, long end) { Set<redis.clients.jedis.Tuple> value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.zrevrangeWithScores(key, start, end); } finally { jedisPool.returnResource(jedis); } return value; } public Set<String> zrevrangeByScore(String key, double max, double min, int offset, int limit) { Set<String> value = null; Jedis jedis = jedisPool.getResource(); try { jedis.auth(password); value = jedis.zrevrangeByScore(key, max, min, offset, limit); } finally { jedisPool.returnResource(jedis); } return value; } }
RedisDAO
package sy.sso; import java.io.Serializable; import java.util.Collection; import java.util.HashSet; import java.util.Set; import javax.servlet.http.HttpSession; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sy.util.base.SerializeUtils; public class RedisDAO { private static Logger logger = LoggerFactory.getLogger(RedisDAO.class); /** * shiro-redis的session对象前缀 */ private final String REDIS_SESSION_PRE = "redis_session:"; private RedisManager redisManager; private int timeOut=1800000;//默认30分钟 public void update(String sessionid,String userName) { this.save(sessionid,userName); } /** * save session * * @param session * @throws UnknownHttpSessionException */ private void save(String sessionid,String userName) { if (userName == null) { logger.error("userName or userName id is null"); return; } byte[] key = getByteKey(sessionid); byte[] value = SerializeUtils.serialize(userName); int expire =timeOut/1000; this.redisManager.set(key, value, expire); } public void delete(String sessionid) { if (sessionid == null) { logger.error("userName or userName id is null"); return; } redisManager.del(this.getByteKey(sessionid)); } public Collection<String> getActives() { Set<String> userNames = new HashSet<String>(); Set<byte[]> keys = redisManager.keys(this.REDIS_SESSION_PRE + "*"); if (keys != null && keys.size() > 0) { for (byte[] key : keys) { String s = (String) SerializeUtils.deserialize(redisManager.get(key)); userNames.add(s); } } return userNames; } public String doRead(Serializable sessionId) { if (sessionId == null) { logger.error("userName id is null"); return null; } String s = (String) SerializeUtils.deserialize(redisManager.get(this.getByteKey(sessionId))); return s; } /** * 获得byte[]型的key * * @param key * @return */ private byte[] getByteKey(Serializable sessionid) { String preKey = this.REDIS_SESSION_PRE + sessionid; return preKey.getBytes(); } public RedisManager getRedisManager() { return redisManager; } public void setRedisManager(RedisManager redisManager) { this.redisManager = redisManager; /** * 初始化redisManager */ this.redisManager.init(); } public int getTimeOut() { return timeOut; } public void setTimeOut(int timeOut) { this.timeOut = timeOut; } }
SSOFilter 这个类里一些装载的类如用户的那些按实际的来,只是提供模式,这里写的是本系统的,如要拿来用,请自行修改.
package sy.sso; import java.io.IOException; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet.FilterConfig; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.lang3.StringUtils; import org.apache.log4j.Logger; import org.apache.shiro.SecurityUtils; import org.apache.shiro.subject.Subject; import org.apache.shiro.subject.Subject.Builder; import org.apache.shiro.util.ThreadContext; import org.apache.shiro.web.mgt.DefaultWebSecurityManager; import org.apache.shiro.web.subject.WebSubject; import org.hibernate.Hibernate; import org.springframework.context.ApplicationContext; import org.springframework.web.context.support.WebApplicationContextUtils; import sy.model.base.frame.SessionInfo; import sy.model.base.frame.Syorganization; import sy.model.base.frame.Syrole; import sy.model.base.frame.Syuser; import sy.model.dtom.Tuser; import sy.service.base.frame.SyuserServiceI; import sy.service.dtom.business.TuserServiceI; import sy.util.base.ConfigUtil; import sy.util.base.HqlFilter; import sy.util.base.IpUtil; /** * 用于redis同步登陆 * * @author miraclerz * */ public class SSOFilter implements Filter { private static final Logger logger = Logger.getLogger(SSOFilter.class); private RedisDAO redisDAO; private SyuserServiceI syuserServiceI; private TuserServiceI tuserServiceI; private DefaultWebSecurityManager securityManager; public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; SessionInfo sessionInfo = null; if(request.getSession().getAttribute(ConfigUtil.getSessionInfoName())!=null) { sessionInfo=(SessionInfo)request.getSession().getAttribute(ConfigUtil.getSessionInfoName()); } String requestURI = request.getRequestURI(); //取得url里的JSESSIONID String JSESSIONID = StringUtils.substringAfterLast(requestURI, "JSESSIONID="); if(request.getSession().getAttribute("JSESSIONID")!=null) {//如果session里的JSESSIONID不为空,表示已经登陆了,JSESSIONID就用这个了 JSESSIONID=(String) request.getSession().getAttribute("JSESSIONID"); } String userName=null; if(sessionInfo==null&&JSESSIONID!=null&&!"".equals(JSESSIONID)) {//如果没登陆且JSESSIONID不为空,即url地址里有JSESSIONID userName=redisDAO.doRead(JSESSIONID); logger.info(userName+":同步登陆"); } if(sessionInfo==null&&userName!=null) { HqlFilter hqlFilter = new HqlFilter(); hqlFilter.addFilter("QUERY_t#loginname_S_EQ", userName); Syuser user = syuserServiceI.getByFilter(hqlFilter); HqlFilter hqlFiltert = new HqlFilter(); hqlFiltert.addFilter("QUERY_t#username_S_EQ", userName); Tuser tuser = tuserServiceI.getByFilter(hqlFiltert); if (user != null&&tuser!=null) { sessionInfo = new SessionInfo(); Hibernate.initialize(user.getSyroles()); Hibernate.initialize(user.getSyorganizations()); Hibernate.initialize(user.getSyresources()); for (Syrole role : user.getSyroles()) { Hibernate.initialize(role.getSyresources()); } for (Syorganization organization : user.getSyorganizations()) { Hibernate.initialize(organization.getSyresources()); } user.setIp(IpUtil.getIpAddr(request)); sessionInfo.setUser(user); //同步登陆shiro SecurityUtils.setSecurityManager(securityManager);// Builder builder = new WebSubject.Builder(request,response); builder.authenticated(true); Subject subject= builder.buildSubject(); //设置用户的session(如果不是shiro,就直接是普通的在这里设置session就行了) subject.getSession().setAttribute(ConfigUtil.getSessionInfoName(), sessionInfo); //在session里保存登陆时的sessionid,这个sessionid会存到redis里去,本系统也会一直用这个作同步 subject.getSession().setAttribute("JSESSIONID", JSESSIONID); ThreadContext.bind(subject);//线程变量中绑定一个已通过验证的Subject对象 } } if(sessionInfo!=null) { redisDAO.update(JSESSIONID,sessionInfo.getUser().getLoginname()); System.out.println("同步session啦=>"+JSESSIONID); } chain.doFilter(request, response); } public void init(FilterConfig filterConfig) throws ServletException { //这些是因为filter无法直接自动装载spring里的bean,于是用下面的方法也取得bean ServletContext context = filterConfig.getServletContext(); ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(context); redisDAO = (RedisDAO) ctx.getBean("redisDAO");//直接以bean名称来取 securityManager = (DefaultWebSecurityManager) ctx.getBean("securityManager"); syuserServiceI=(SyuserServiceI)ctx.getBean("syuserServiceImpl"); tuserServiceI=(TuserServiceI)ctx.getBean("tuserServiceImpl"); /* String[] syuserServices=ctx.getBeanNamesForType(SyuserServiceI.class);//取得所有这个接口的实现类的bean名(以接口装载的不知道bean名是啥) syuserServiceI = (SyuserServiceI)ctx.getBean(syuserServices[0]);//取第一个实现类名 logger.info("实现类名:"+syuserServices[0]); String[] tuserServices=ctx.getBeanNamesForType(TuserServiceI.class); tuserServiceI = (TuserServiceI)ctx.getBean(tuserServices[0]); */ } public void destroy() { } }
在spring 的配置文件里要加上redis的配置
<bean id="redisDAO" class="sy.sso.RedisDAO"> <property name="timeOut" value="1800000"></property> <property name="redisManager" > <bean class="sy.sso.RedisManager"> <!-- <property name="host" value="172.16.6.3"></property> --> <property name="host" value="127.0.0.1"></property> <property name="dbindex" value="0"></property> <property name="password" value="123456"></property> </bean> </property> </bean>
在web.xml里加上(shiro的filter的前面)
<!--sso同步登陆filter --> <filter> <filter-name>ssofilter</filter-name> <filter-class>sy.sso.SSOFilter</filter-class> </filter> <filter-mapping> <filter-name>ssofilter</filter-name> <url-pattern>/*.sy</url-pattern> </filter-mapping> <filter-mapping> <filter-name>ssofilter</filter-name> <url-pattern>*.jsp</url-pattern> </filter-mapping>
其它系统同步时也一样是这样,配置一个ssoFilter,在这个filter里先判断是否已经登陆,如果已经登陆就直接跳过不理了,如果没登陆就判断是否地址上带有JSESSIONID,如果有就取出来,去redis里看有没有这个值,如果没有就忽略跳过,如果有就取出用户名,用这个用户名去自己的系统里把用户信息取出来,然后设置到session里就完成同步了.
在oa里还要在session的listener里对session的创建和销毁里要同步设置redis信息;
/** * 向session里增加属性时调用(用户成功登陆后会调用) */ public void attributeAdded(HttpSessionBindingEvent evt) { String name = evt.getName(); logger.debug("向session存入属性:" + name); if (ConfigUtil.getSessionInfoName().equals(name)) {// 如果存入的属性是sessionInfo的话 HttpSession session = evt.getSession(); SessionInfo sessionInfo = (SessionInfo) session.getAttribute(name); if (sessionInfo != null) { // System.out.println(sessionInfo.getUser().getName() + "登录了"); //SyonlineServiceI syonlineService = (SyonlineServiceI) ctx.getBean("syonlineServiceImpl"); Syonline online = new Syonline(); online.setType("1");// 登录 online.setLoginname(sessionInfo.getUser().getLoginname()); online.setIp(sessionInfo.getUser().getIp()); syonlineService.save(online); //登陆成功后把信息存到redis session.setAttribute("JSESSIONID", evt.getSession().getId()); redisDAO.update(evt.getSession().getId(),sessionInfo.getUser().getLoginname()); } } }
/** * session销毁(用户退出系统时会调用) */ public void sessionDestroyed(HttpSessionEvent evt) { HttpSession session = evt.getSession(); if (session != null) { logger.debug("session销毁:" + session.getId()); SessionInfo sessionInfo = (SessionInfo) session.getAttribute(ConfigUtil.getSessionInfoName()); if (sessionInfo != null) { // System.out.println(sessionInfo.getUser().getName() + "注销了"); // SyonlineServiceI syonlineService = (SyonlineServiceI) ctx.getBean("syonlineServiceImpl"); Syonline online = new Syonline(); online.setType("0");// 注销 online.setLoginname(sessionInfo.getUser().getLoginname()); online.setIp(sessionInfo.getUser().getIp()); syonlineService.save(online); //用户退出后把用户信息从redis里删除 Object JSESSIONID=session.getAttribute("JSESSIONID"); if(JSESSIONID!=null) { redisDAO.delete((String) JSESSIONID); } } } }
跳转的地址类似这样写:
<a target="_blank" href="http://127.0.0.1:8089/oa/login.jsp;JSESSIONID=<%=request.getSession().getAttribute("JSESSIONID")%>">另一个系统go</a>
OK,系统同步登陆就搞定了!
相关推荐
综上所述,"tomcat7 + redis + nginx 实现session共享的jar包"是通过利用Redis作为中央session存储,结合Nginx的负载均衡能力,解决了分布式环境下的session一致性问题。这个解决方案既保证了用户体验的连续性,也...
通过以上步骤,我们可以实现基于Redis的Session共享,提高Web应用的可扩展性和可用性。这种方式不仅解决了跨服务器的Session同步问题,还提供了Session持久化的能力,即使Tomcat重启,用户的状态也能得以保留。同时...
本文将深入探讨如何利用Spring Session与Redis来实现这一功能。 首先,Spring Session是一个开源项目,由Pivotal Software开发,它扩展了Spring MVC,提供了对HTTP会话(session)的管理支持。Spring Session的核心...
"集群redis实现session共享jar包之tomcat7"这个主题涉及到的是如何在基于Tomcat 7的Web应用集群中,利用Redis作为中央存储来共享用户的Session数据。下面将详细解释这一技术的实现原理和步骤。 首先,理解Session...
通过以上步骤,我们就成功地利用Shiro和Redis实现了session共享。这种解决方案有助于提升大型Web应用的可扩展性和健壮性,同时也简化了跨服务器用户状态的管理。在实际开发中,可以根据项目需求进行适当的调整和优化...
通过以上步骤,我们可以成功地在`Tomcat7`中利用`Redis`实现Session共享,提高了系统的可扩展性和可用性。这种方法不仅适用于`Tomcat7`,还可以应用于其他支持自定义Session管理的Servlet容器。
这个小例子"nginx+tomcat+redis完成session共享"旨在演示如何通过这三种技术实现跨服务器的用户会话共享,以提升用户体验并简化系统管理。以下是这些技术及其在会话共享中的作用: 1. **Nginx**:Nginx是一款高性能...
而Redis作为一款高效的内存数据存储系统,常被用来作为Session的集中存储,以实现跨服务器的Session共享。 Shiro与Redis结合,可以通过自定义SessionDAO来实现在集群环境下的Session共享。首先,我们需要引入Shiro...
Springboot实现多服务器session共享是指在分布式系统中,每个服务器上的Session可以共享,实现 Session 的同步和共享,从而解决了在分布式环境中Session不一致的问题。下面是关于Springboot实现多服务器session共享...
综上所述,"适配与Tomcat7、8、9的redis session共享jar包"提供了一种有效的方法,解决了在多台Tomcat服务器之间共享session的挑战,利用Redis的高效存储和检索能力,提高了Web应用的可扩展性和用户体验。...
本项目“redissession共享代码”提供了一个简单的实例,帮助开发者理解如何利用Redis来实现Session共享。 首先,我们需要了解Session的基本概念。在HTTP协议中,由于其无状态特性,无法在多个请求之间保持用户的...
通过以上步骤,你就可以实现Redis和Tomcat之间的session共享,解决了分布式环境下的会话一致性问题。这种方案对于需要高并发、高可用性的Web应用尤其重要,因为它可以确保用户在不同服务器之间切换时仍能保持登录...
**Redis与Tomcat Session共享** 的实现原理是,将Tomcat中的Session数据存储在Redis中,而不是在每个Tomcat服务器的内存中。每当有Session创建、更新或删除时,都会通过一个中间件(通常是Spring Session或者Apache ...
在此场景中,Redis用于session共享,解决了多台Tomcat服务器之间session同步的问题。当用户在任一服务器上登录并创建session后,session数据会被存储在Redis中。后续的请求无论被Nginjx路由到哪台服务器,都可以从...
综上所述,"redis+nginx session共享jar包下载支持tomcat7"是一种有效的方法,它利用Redis进行Session存储,通过Nginx实现负载均衡和Session同步,使得在多台Tomcat服务器上能够共享用户会话,提高系统的可扩展性和...
为了解决这个问题,我们可以利用Redis来实现基于集群的session共享,这就是“基于redis的集群session共享jar包”所涉及的核心内容。 Redis是一个高性能的键值数据库,特别适合用来做缓存和数据共享。将session存储...
本资源"tomcat7+redis单点 session共享jar"提供了针对Tomcat7服务器和Redis数据存储的一个解决方案,以实现跨服务器的session共享。 **Tomcat7** 是一个广泛使用的开源Java Servlet容器,它实现了Java EE的Web应用...
本篇文章将详细探讨如何在Redis+Tomcat集群配置中实现Session共享。 首先,我们需要理解什么是Session。Session是Web应用中用于存储用户状态的一种机制,通常用于保存用户的登录信息、购物车等数据。在单台服务器...
接下来,我们将详细讲解如何配置和实现Tomcat8与Redis的Session共享: 1. **安装Redis**: 在开始之前,确保已经在服务器上安装并运行了Redis。可以在Redis官网下载相应平台的二进制包,解压后启动Redis服务器。 2....
tomcat8 Redis集群 同步Session 中用到的jar 附带tomcat content.xml配置文件