redis-session改造过程

老系统用的比较老的服务器,所以用tomcat6版本的redis-session组件

github地址:https://github.com/jcoleman/tomcat-redis-session-manager

tag原码下载地址:https://github.com/jcoleman/tomcat-redis-session-manager/releases/tag/1.2-tomcat-6

改造就两步

第一步:添加jar包

第二步:修改配置

下面做详细说明

第一步:添加jar包

下载原码,打jar包,因为系统用的jdk6。所以要指定java版本对项目进行编译

build.gradle添加下面代码:

compileJava {
  sourceCompatibility = 1.6
  targetCompatibility = 1.6
}

然后在idea中把相关的jar包拉出来

tomcat-redis-session-manager-1.2-tomcat-6-1.2.jar

commons-pool-1.6.jar

jedis-2.0.0.jar

放到相应的目录下(下面分别是jboss5.1GA的存放路径,和 tomcat6的存放路径)

{JBOSS_HOME}\server\default\lib

{TOMCAT_HOME}\lib

第二步:修改配置

修改位置

{JBOSS_HOME}\server\default\deploy\jbossweb.sar\context.xml
{TOMCAT_HOME}\conf\context.xml

修改内容

<?xml version='1.0' encoding='utf-8'?>

<Context>

      <WatchedResource>WEB-INF/web.xml</WatchedResource>

      <!-- tomcat-redis-session (can not place chinese chars here. or would throw Exception, can not parse) -->

      <Valve className="com.radiadesign.catalina.session.RedisSessionHandlerValve" />

      <Manager className="com.radiadesign.catalina.session.RedisSessionManager" host="redis-ip" port="6379" database="0" maxInactiveInterval="1800" password="password"/>

</Context>

添加 <valve> 和 <mavager> 节点即可

第三:bug修复

配置之后 redis session生效了。但是有个bug。就是新开浏览器登陆要输入两次验证码。通过调试发现代码重写的地方不对。

以下是ManagerBase.java的代码。可以看到 无参的createSession()方法调用了有参的createSession方法

ManagerBase

但是原码只重写了createSession()方法。没有重写createSession(String sessionId)方法,导致调用无参方法创建session的时候并没有走redis。cookie过来从redis里无法获取,就重新生成session

注意加上这一段代码:this.currentSessionIsPersisted.set(false);

RedisSessionManager
  // 重写的方法加上参数。原来重写的是createSession()。这样无论是调用有参还是无参,都会走这个方法
  @Override
  public Session createSession(String sessionId) {
    RedisSession session = (RedisSession)createEmptySession();

    // Initialize the properties of the new session and return it
    session.setNew(true);
    session.setValid(true);
    session.setCreationTime(System.currentTimeMillis());
    session.setMaxInactiveInterval(getMaxInactiveInterval());

    String jvmRoute = getJvmRoute();

    Boolean error = true;
    Jedis jedis = null;

    try {
      jedis = acquireConnection();

      // Ensure generation of a unique session identifier.
      do {
        if(sessionId == null)
          sessionId = generateSessionId();

        if (jvmRoute != null) {
          sessionId += '.' + jvmRoute;
        }
      } while (jedis.setnx(sessionId.getBytes(), NULL_SESSION) == 1L); // 1 = key set; 0 = key already existed

      /* Even though the key is set in Redis, we are not going to flag
         the current thread as having had the session persisted since
         the session isn't actually serialized to Redis yet.
         This ensures that the save(session) at the end of the request
         will serialize the session into Redis with 'set' instead of 'setnx'. */

      error = false;
        // 注意这一步,在调用save的时候,会根据这个条件判断是否保存到redis。原码上是没有这一句的
      this.currentSessionIsPersisted.set(false);
      session.setId(sessionId);
      session.tellNew();
    } finally {
      if (jedis != null) {
        returnConnection(jedis, error);
      }
    }

猜你喜欢

转载自blog.csdn.net/u011498478/article/details/117807822
今日推荐