实际项目中用shiro做权限与登录验证,并做单点登录,单点登录克服有浏览器cookie的sessionID的统一与redis缓存的sessionID统一 也就是所有的sessionID要一致。
怕忘记并记录下,实际项目redis采用集群。
一、shiro缓存为redis毋庸置疑
1、RedisConfig
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.sso.common.redis;
import com.sso.common.redis.shiro.FastJsonRedisSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import java.util.HashSet;
import java.util.Set;
@Configuration
@Component
public class RedisConfig {
@Value("${spring.redis.pool.max-idle}")
private Integer maxIdle;
// @Value("${spring.redis.}")
// private Integer maxTotal;
@Value("${spring.redis.pool.max-wait}")
private Integer maxWaitMillis;
// @Value("${redis.minEvictableIdleTimeMillis}")
// private Integer minEvictableIdleTimeMillis;
// @Value("${redis.numTestsPerEvictionRun}")
// private Integer numTestsPerEvictionRun;
// @Value("${redis.timeBetweenEvictionRunsMillis}")
// private long timeBetweenEvictionRunsMillis;
// @Value("${redis.testOnBorrow}")
// private boolean testOnBorrow;
// @Value("${redis.testWhileIdle}")
// private boolean testWhileIdle;
@Value("${spring.redis.cluster.nodes}")
private String clusterNodes;
@Value("${spring.redis.cluster.max-redirects}")
private Integer mmaxRedirectsac;
/**
* JedisPoolConfig 连接池
*
* @return
*/
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大空闲数
jedisPoolConfig.setMaxIdle(maxIdle);
// 连接池的最大数据库连接数
//jedisPoolConfig.setMaxTotal(maxTotal);
// 最大建立连接等待时间
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
// 逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
//jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
// 每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
//jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
// 逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
//jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
// 是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
//jedisPoolConfig.setTestOnBorrow(testOnBorrow);
// 在空闲时检查有效性, 默认false
//jedisPoolConfig.setTestWhileIdle(testWhileIdle);
return jedisPoolConfig;
}
/**
* Redis集群的配置
*
* @return RedisClusterConfiguration
* @throws
* @autor lpl
* @date 2017年12月22日
*/
@Bean
public RedisClusterConfiguration redisClusterConfiguration() {
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
//Set clusterNodes
String[] serverArray = clusterNodes.split(",");
Set nodes = new HashSet();
for (String ipPort : serverArray) {
String[] ipAndPort = ipPort.split(":");
nodes.add(new RedisNode(ipAndPort[0].trim(), Integer.valueOf(ipAndPort[1])));
}
redisClusterConfiguration.setClusterNodes(nodes);
redisClusterConfiguration.setMaxRedirects(mmaxRedirectsac);
return redisClusterConfiguration;
}
/**
* 配置工厂
*
* @param @param jedisPoolConfig
* @param @return
* @return JedisConnectionFactory
* @throws
* @Title: JedisConnectionFactory
* @autor lpl
* @date 2017年12月22日
*/
@Bean
public JedisConnectionFactory JedisConnectionFactory(JedisPoolConfig jedisPoolConfig, RedisClusterConfiguration redisClusterConfiguration) {
JedisConnectionFactory JedisConnectionFactory = new JedisConnectionFactory(redisClusterConfiguration, jedisPoolConfig);
return JedisConnectionFactory;
}
@Bean
public JedisCluster jedisCluster(JedisConnectionFactory JedisConnectionFactory) {
JedisCluster jedisCluster = (JedisCluster)JedisConnectionFactory.getConnection().getNativeConnection();
return jedisCluster;
}
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate template = new RedisTemplate();
// 使用fastjson序列化
FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
// value值的序列化采用fastJsonRedisSerializer
template.setValueSerializer(fastJsonRedisSerializer);
template.setHashValueSerializer(fastJsonRedisSerializer);
// key的序列化采用StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
View Code
2、RedisUtil
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.sso.common.redis;
import com.sso.common.redis.shiro.FastJsonRedisSerializer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import java.util.HashSet;
import java.util.Set;
@Configuration
@Component
public class RedisConfig {
@Value("${spring.redis.pool.max-idle}")
private Integer maxIdle;
// @Value("${spring.redis.}")
// private Integer maxTotal;
@Value("${spring.redis.pool.max-wait}")
private Integer maxWaitMillis;
// @Value("${redis.minEvictableIdleTimeMillis}")
// private Integer minEvictableIdleTimeMillis;
// @Value("${redis.numTestsPerEvictionRun}")
// private Integer numTestsPerEvictionRun;
// @Value("${redis.timeBetweenEvictionRunsMillis}")
// private long timeBetweenEvictionRunsMillis;
// @Value("${redis.testOnBorrow}")
// private boolean testOnBorrow;
// @Value("${redis.testWhileIdle}")
// private boolean testWhileIdle;
@Value("${spring.redis.cluster.nodes}")
private String clusterNodes;
@Value("${spring.redis.cluster.max-redirects}")
private Integer mmaxRedirectsac;
/**
* JedisPoolConfig 连接池
*
* @return
*/
@Bean
public JedisPoolConfig jedisPoolConfig() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
// 最大空闲数
jedisPoolConfig.setMaxIdle(maxIdle);
// 连接池的最大数据库连接数
//jedisPoolConfig.setMaxTotal(maxTotal);
// 最大建立连接等待时间
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
// 逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
//jedisPoolConfig.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
// 每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
//jedisPoolConfig.setNumTestsPerEvictionRun(numTestsPerEvictionRun);
// 逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
//jedisPoolConfig.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
// 是否在从池中取出连接前进行检验,如果检验失败,则从池中去除连接并尝试取出另一个
//jedisPoolConfig.setTestOnBorrow(testOnBorrow);
// 在空闲时检查有效性, 默认false
//jedisPoolConfig.setTestWhileIdle(testWhileIdle);
return jedisPoolConfig;
}
/**
* Redis集群的配置
*
* @return RedisClusterConfiguration
* @throws
* @autor lpl
* @date 2017年12月22日
*/
@Bean
public RedisClusterConfiguration redisClusterConfiguration() {
RedisClusterConfiguration redisClusterConfiguration = new RedisClusterConfiguration();
//Set clusterNodes
String[] serverArray = clusterNodes.split(",");
Set nodes = new HashSet();
for (String ipPort : serverArray) {
String[] ipAndPort = ipPort.split(":");
nodes.add(new RedisNode(ipAndPort[0].trim(), Integer.valueOf(ipAndPort[1])));
}
redisClusterConfiguration.setClusterNodes(nodes);
redisClusterConfiguration.setMaxRedirects(mmaxRedirectsac);
return redisClusterConfiguration;
}
/**
* 配置工厂
*
* @param @param jedisPoolConfig
* @param @return
* @return JedisConnectionFactory
* @throws
* @Title: JedisConnectionFactory
* @autor lpl
* @date 2017年12月22日
*/
@Bean
public JedisConnectionFactory JedisConnectionFactory(JedisPoolConfig jedisPoolConfig, RedisClusterConfiguration redisClusterConfiguration) {
JedisConnectionFactory JedisConnectionFactory = new JedisConnectionFactory(redisClusterConfiguration, jedisPoolConfig);
return JedisConnectionFactory;
}
@Bean
public JedisCluster jedisCluster(JedisConnectionFactory JedisConnectionFactory) {
JedisCluster jedisCluster = (JedisCluster)JedisConnectionFactory.getConnection().getNativeConnection();
return jedisCluster;
}
@Bean
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate template = new RedisTemplate();
// 使用fastjson序列化
FastJsonRedisSerializer fastJsonRedisSerializer = new FastJsonRedisSerializer(Object.class);
// value值的序列化采用fastJsonRedisSerializer
template.setValueSerializer(fastJsonRedisSerializer);
template.setHashValueSerializer(fastJsonRedisSerializer);
// key的序列化采用StringRedisSerializer
template.setKeySerializer(new StringRedisSerializer());
template.setHashKeySerializer(new StringRedisSerializer());
template.setConnectionFactory(redisConnectionFactory);
return template;
}
}
View Code
3、FastJsonRedisSerializer
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.sso.common.redis.shiro;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;
import java.nio.charset.Charset;
/**
* @author yuduojia
* @date 2018/9/14 14:42
*/
public class FastJsonRedisSerializer implements RedisSerializer {
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private Class clazz;
public FastJsonRedisSerializer(Class clazz) {
super();
this.clazz = clazz;
}
@Override
public byte[] serialize(T t) throws SerializationException {
if (null == t) {
return new byte[0];
}
return JSON.toJSONString(t, SerializerFeature.WriteClassName).getBytes(DEFAULT_CHARSET);
}
@Override
public T deserialize(byte[] bytes) throws SerializationException {
if (null == bytes || bytes.length |