Spring,shiro,redis Implementing session Sharing

Source: Internet
Author: User
Tags redis stub tostring redis server

Spring-shiro integration please see the first step of shiro springmvc integration

Spring-redis integration please see spring redis integration

The redis jar used is as follows

<dependency>
<groupId> redis.clients </ groupId>
<artifactId> jedis </ artifactId>
<version> 2.6.2 </ version>
</ dependency>
<dependency>
<groupId> org.springframework.data </ groupId>
<artifactId> spring-data-redis </ artifactId>
<version> 1.4.1.RELEASE </ version>
</ dependency>
<dependency>
<groupId> org.apache.commons </ groupId>
<artifactId> commons-pool2 </ artifactId>
<version> 2.2 </ version>
</ dependency>
If you want to use redis to manage the session, you need to add the sessionDAO attribute to the session manager of shiro as follows

<bean id = "sessionManager"
class = "org.apache.shiro.web.session.mgt.DefaultWebSessionManager">
<property name = "sessionDAO" ref = "sessionDao"> </ property>
<property name = "globalSessionTimeout" value = "60000" />
<!-Delete invalid session->
<property name = "sessionValidationSchedulerEnabled" value = "true" />
<property name = "sessionListeners" ref = "myShiroSessionListener"> </ property>
</ bean>
<bean id = "myShiroSessionListener" class = "com.zyc.listener.MyShiroSessionListener"> </ bean>
<bean id = "sessionDao" class = "com.zyc.security.SessionDao">
<property name = "redisUtil" ref = "redisUtil"> </ property>
</ bean>
Redis configuration is as follows
<bean id = "poolConfig" class = "redis.clients.jedis.JedisPoolConfig">
<property name = "maxIdle" value = "100" />
<property name = "maxWaitMillis" value = "10000" />
<property name = "testOnBorrow" value = "true" />
</ bean>
<!-redis server center->
<bean id = "connectionFactory"
class = "org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name = "poolConfig" ref = "poolConfig" />
<property name = "port" value = "63791" />
<property name = "hostName" value = "127.0.0.1" />
<!-<property name = "password" value = "$ {redis.password}" />->
<property name = "timeout" value = "10000"> </ property>
</ bean>
<bean id = "redisTemplate" class = "org.springframework.data.redis.core.RedisTemplate">
<property name = "connectionFactory" ref = "connectionFactory" />
<property name = "keySerializer">
<bean
class = "org.springframework.data.redis.serializer.StringRedisSerializer" />
</ property>
<property name = "valueSerializer">
<bean
class = "org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</ property>
</ bean>
sessionDao needs to implement the EnterpriseCacheSessionDAO class or CachingSessionDAO class. Let us take the EnterpriseCacheSessionDAO class as an example:

package com.zyc.security;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutput;
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 SessionDao extends EnterpriseCacheSessionDAO {
The
private RedisUtil redisUtil;
public RedisUtil getRedisUtil () {
return redisUtil;
}

public void setRedisUtil (RedisUtil redisUtil) {
this.redisUtil = redisUtil;
}

// Create session and save to database
    @Override
    protected Serializable doCreate (Session session) {
        Serializable sessionId = super.doCreate (session);
        redisUtil.set (sessionId.toString (), sessionToByte (session), 1 * 60L);
        
        return sessionId;
    }

    // Get session
    @Override
    protected Session doReadSession (Serializable sessionId) {
        // Get the session from the cache first, if not, go to the database to get it
        Session session = super.doReadSession (sessionId);
        if (session == null) {
            byte [] bytes = (byte []) redisUtil.get (sessionId.toString ());
            if (bytes! = null && bytes.length> 0) {
                session = byteToSession (bytes);
            }
        }
        return session;
    }

    // Update the last access time of the session
    @Override
    protected void doUpdate (Session session) {
        super.doUpdate (session);
        redisUtil.set (session.getId (). toString (), sessionToByte (session), 1 * 60L);
    }

    // delete session
    @Override
    protected void doDelete (Session session) {
        super.doDelete (session);
        redisUtil.remove (session.getId (). toString ());
    }

    // Convert the session object to byte and save it in redis
    public byte [] sessionToByte (Session session) {
        ByteArrayOutputStream bo = new ByteArrayOutputStream ();
        byte [] bytes = null;
        try {
            ObjectOutput oo = new ObjectOutputStream (bo);
            oo.writeObject (session);
            bytes = bo.toByteArray ();
        } catch (IOException e) {
            e.printStackTrace ();
        }
        return bytes;
    }
    
    // restore byte to 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;
    }
}
The RedisUtil tool class is as follows:
package com.zyc.security;

import java.io.Serializable;
import java.util.Set;
import java.util.concurrent.TimeUnit;

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

/ **
 * @author: zyc
 * @date: October 24, 2017, 9:26:55 am
 * @description:
 * @version:
 *
 * /
@Service ("redisUtil")
public class RedisUtil {

private Logger logger = LoggerFactory.getLogger (RedisUtil.class);

@Resource (name = "redisTemplate")
private RedisTemplate <Serializable, Object> redisTemplate;

/ **
* Batch delete the corresponding value
*
* @param keys
* /
public void remove (final String ... keys) {
for (String key: keys) {
remove (key);
}
}

/ **
* Delete keys in batch
*
* @param pattern
* /
public void removePattern (final String pattern) {
Set <Serializable> keys = redisTemplate.keys (pattern);
if (keys.size ()> 0)
redisTemplate.delete (keys);
}

/ **
* Delete the corresponding value
*
* @param key
* /
public void remove (final String key) {
if (exists (key)) {
redisTemplate.delete (key);
}
}

/ **
* Determine whether there is a corresponding value in the cache
*
* @param key
* @return
* /
public boolean exists (final String key) {
return redisTemplate.hasKey (key);
}

/ **
* Get all keys
*
* @return
* /
public Set <Serializable> keys () {
return redisTemplate.keys ("*");
}

/ **
* Read cache
*
* @param key
* @return
* /
public Object get (final String key) {
Object result = null;
ValueOperations <Serializable, Object> operations = redisTemplate
.opsForValue ();
result = operations.get (key);
return result;
}

/ **
* Write cache
*
* @param key
* @param value
* @return
* /
public boolean set (final String key, Object value) {
boolean result = false;
try {
ValueOperations <Serializable, Object> operations = redisTemplate
.opsForValue ();
operations.set (key, value);
result = true;
} catch (Exception e) {
e.printStackTrace ();
}
return result;
}

/ **
* Write cache
*
* @param key
* @param value
* @return
* /
public boolean set (final String key, Object value, Long expireTime) {
boolean result = false;
try {
ValueOperations <Serializable, Object> operations = redisTemplate
.opsForValue ();
operations.set (key, value);
redisTemplate.expire (key, expireTime, TimeUnit.SECONDS);
result = true;
} catch (Exception e) {
e.printStackTrace ();
}
return result;
}

public void setRedisTemplate (
RedisTemplate <Serializable, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
}

The session monitoring class is as follows (writable but not written, the listener needs to be removed in the configuration without writing):
package com.zyc.listener;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.SessionListener;

import com.zyc.security.RedisUtil;
import com.zyc.security.SpringContext;

public class MyShiroSessionListener implements SessionListener {

@Override
public void onStart (Session session) {
The
}

@Override
public void onStop (Session session) {
// TODO Auto-generated method stub
System.out.println ("onStop ===" + session.getId ());
RedisUtil redisUtil = (RedisUtil) SpringContext.getBean ("redisUtil");
redisUtil.remove (session.getId (). toString ());
}

@Override
public void onExpiration (Session session) {
System.out.println ("onExpiration ===" + session.getId ());
RedisUtil redisUtil = (RedisUtil) SpringContext.getBean ("redisUtil");
redisUtil.remove (session.getId (). toString ());

}

}
SpringContext is a tool class for obtaining beans:
package com.zyc.security;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import org.springframework.stereotype.Component;

@Component
public class SpringContext implements ApplicationContextAware {

private static ApplicationContext applicationContext;
@Override
public void setApplicationContext (ApplicationContext arg0)
throws BeansException {
// TODO Auto-generated method stub
applicationContext = arg0;
}
public static Object getBean (String name) {
if (applicationContext! = null) {
return applicationContext.getBean (name);
}
return null;
}

}


Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.