2016-11-30 67 views
0

我有兩個分佈式Web應用程序A和B(A與B相同),我使用shiro在兩個應用程序之間共享http會話。但我不知道如何實施它,我想要一些幫助。 任何幫助將不勝感激:)如何在分佈式系統中共享shiro會話?

+0

我想你可以使用redis或其他分佈式緩存來存儲shiro的會話。 – JonahCui

回答

-1

我希望shiro-redis可以給你一些幫助。也許這個代碼不是最近的。但你可以研究他的方法。然後你可以創建你的代碼。


我要給你點代碼如下:
1 sessionDao

import java.io.ByteArrayInputStream; 
import java.io.ByteArrayOutputStream; 
import java.io.IOException; 
import java.io.ObjectInputStream; 
import java.io.ObjectOutputStream; 
import java.io.Serializable; 

import org.apache.shiro.session.Session; 
import org.apache.shiro.session.mgt.SimpleSession; 
import org.apache.shiro.session.mgt.eis.EnterpriseCacheSessionDAO; 

public class SessionRedisDao extends EnterpriseCacheSessionDAO { 

    // create session , store to db 
    @Override 
    protected Serializable doCreate(Session session) { 
     Serializable sessionId = super.doCreate(session); 
     RedisDb.setObject(sessionId.toString().getBytes(), sessionToByte(session)); 

     return sessionId; 
    } 

    // get session 
    @Override 
    protected Session doReadSession(Serializable sessionId) { 
     // firstly get session from cache,if null then get it from db 
     Session session = super.doReadSession(sessionId); 
     if(session == null){ 
      byte[] bytes = RedisDb.getObject(sessionId.toString().getBytes()); 
      if(bytes != null && bytes.length > 0){ 
       session = byteToSession(bytes);  
      } 
     } 
     return session; 
    } 


    @Override 
    protected void doUpdate(Session session) { 
     super.doUpdate(session); 
     RedisDb.setObject(session.getId().toString().getBytes(), sessionToByte(session)); 
    } 

    // delete session 
    @Override 
    protected void doDelete(Session session) { 
     super.doDelete(session); 
     RedisDb.delString(session.getId() + ""); 
    } 

    // convert session object to byte, then store it to redis 
    public byte[] sessionToByte(Session session){ 
     ByteArrayOutputStream bo = new ByteArrayOutputStream(); 
     byte[] bytes = null; 
     try { 
      ObjectOutputStream oo = new ObjectOutputStream(bo); 
      oo.writeObject(session); 
      bytes = bo.toByteArray(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
     return bytes; 
    } 

    // restore session 
    public Session byteToSession(byte[] bytes){ 
     ByteArrayInputStream bi = new ByteArrayInputStream(bytes); 
     ObjectInputStream in; 
     SimpleSession session = null; 
     try { 
      in = new ObjectInputStream(bi); 
      session = (SimpleSession) in.readObject(); 
     } catch (ClassNotFoundException e) { 
      e.printStackTrace(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 

     return session; 
    } 

} 
  • redis的操作者

    import java.util.Arrays; 
    import java.util.Date; 
    import java.util.Set; 
    import redis.clients.jedis.Jedis; 
    import redis.clients.jedis.JedisPool; 
    import redis.clients.jedis.JedisPoolConfig; 
    
    public class RedisDb { 
    private static JedisPool jedisPool; 
    // session expire time 
    private static int expireTime = 1800; 
    private static int countExpireTime = 2*24*3600; 
    private static String password = "123456"; 
    private static String redisIp = "10.10.31.149"; 
    private static int redisPort = 6379; 
    private static int maxActive = 200; 
    private static int maxIdle = 200; 
    private static long maxWait = 5000; 
    private static Logger logger = Logger.getLogger(RedisDb.class); 
    
    static { 
        initPool(); 
    } 
    // init connect pool 
    public static void initPool(){ 
        JedisPoolConfig config = new JedisPoolConfig(); 
        config.setMaxTotal(maxActive); 
        config.setMaxIdle(maxIdle); 
        config.setMaxWaitMillis(maxWait); 
        config.setTestOnBorrow(false); 
        jedisPool = new JedisPool(config, redisIp, redisPort, 10000, password); 
    } 
    // get connect from pool 
    public static Jedis getJedis(){ 
        Jedis jedis = null; 
        try{ 
         jedis = jedisPool.getResource(); 
         //   jedis.auth(password); 
        } catch(Exception e){ 
         ExceptionCapture.logError(e); 
        } 
    
        return jedis; 
    } 
    // recycle connection 
    public static void recycleJedis(Jedis jedis){ 
        if(jedis != null){ 
         try{ 
          jedis.close(); 
         } catch(Exception e){ 
          ExceptionCapture.logError(e); 
         } 
        } 
    } 
    // save string 
    public static void setString(String key, String value){ 
        Jedis jedis = getJedis(); 
        if(jedis != null){ 
         try{ 
          jedis.set(key, value); 
         } catch(Exception e){ 
          ExceptionCapture.logError(e); 
         } finally{ 
          recycleJedis(jedis); 
         } 
        } 
    
    } 
    // get string data 
    public static String getString(String key){ 
        Jedis jedis = getJedis(); 
        String result = ""; 
        if(jedis != null){ 
         try{ 
          result = jedis.get(key); 
         }catch(Exception e){ 
          ExceptionCapture.logError(e); 
         } finally{ 
          recycleJedis(jedis); 
         } 
        } 
    
        return result; 
    } 
    // delete string 
    public static void delString(String key){ 
        Jedis jedis = getJedis(); 
        if(jedis != null){ 
         try{ 
          jedis.del(key); 
         }catch(Exception e){ 
          ExceptionCapture.logError(e); 
         } finally{ 
          recycleJedis(jedis); 
         } 
        } 
    } 
    // save byte data 
    public static void setObject(byte[] key, byte[] value){ 
        Jedis jedis = getJedis(); 
        String result = ""; 
        if(jedis != null){ 
         try{ 
          if(!jedis.exists(key)){ 
           jedis.set(key, value); 
          } 
          // redis中session過期時間 
          jedis.expire(key, expireTime); 
         } catch(Exception e){ 
          ExceptionCapture.logError(e); 
         } finally{ 
          recycleJedis(jedis); 
         } 
        } 
    } 
    // get byte data 
    public static byte[] getObject(byte[] key){ 
        Jedis jedis = getJedis(); 
        byte[] bytes = null; 
        if(jedis != null){ 
         try{ 
          bytes = jedis.get(key);; 
         }catch(Exception e){ 
          ExceptionCapture.logError(e); 
         } finally{ 
          recycleJedis(jedis); 
         } 
        } 
        return bytes; 
    
    } 
    
    // update byte data 
    public static void updateObject(byte[] key){ 
        Jedis jedis = getJedis(); 
        if(jedis != null){ 
         try{ 
          // redis中session過期時間 
          jedis.expire(key, expireTime); 
         }catch(Exception e){ 
          ExceptionCapture.logError(e); 
         } finally{ 
          recycleJedis(jedis); 
         } 
        } 
    
    } 
    
    // key value add 1 
    public static void inc(String key){ 
        Jedis jedis = getJedis(); 
        if(jedis != null){ 
         try{ 
          if(!jedis.exists(key)){ 
           jedis.set(key, "1"); 
           jedis.expire(key, countExpireTime); 
          } else { 
           // 加1 
           jedis.incr(key); 
          } 
         }catch(Exception e){ 
          ExceptionCapture.logError(e); 
         } finally{ 
          recycleJedis(jedis); 
         } 
        } 
    } 
    
    // get all keys 
    public static Set<String> getAllKeys(String pattern){ 
        Jedis jedis = getJedis(); 
        if(jedis != null){ 
         try{ 
          return jedis.keys(pattern); 
         }catch(Exception e){ 
          ExceptionCapture.logError(e); 
         } finally{ 
          recycleJedis(jedis); 
         } 
        } 
        return null; 
    } 
    

    }

  • shiro的會話只是一個對象,所以如果你想分享會話,你需要將它存儲在一個共享的地方。

    0

    Shiro有Hazelcast和EhCache的官方模塊。 上面的Hazelcast通過兩個應用程序共享會話的示例鏈接到博客文章。