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;
}
}