一、问题描述
整合SpringSecurity时,
- 认证通过后把LoginUser信息存储到redis缓存中;
- 校验token通过后,读取redis缓存中的LoginUser数据失败,
报错
:
Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException:
Cannot construct instance of
`org.springframework.security.core.authority.SimpleGrantedAuthority`
(although at least one Creator exists):
cannot deserialize from Object value (no delegate- or property-based Creator)
二、原因分析:
- 整合SpringSecurity时,我们自己定义的LoginUser实体类需要继承SpringSecurity的UserDetails接口,实现其中的方法。
- 认证通过后把LoginUser信息存储到redis缓存中,会把接口实现类中的一些类变量序列化到redis中。
- 校验token通过后,反序列化LoginUser,读取redis缓存中的LoginUser数据就会
失败报错
。
后来测试的时候,发现使用fastjson进行序列化和反序列化,就不会出现这个问题
可以使用fastjson来避免这个问题,测试fastjson的1.2.49版本和2.0.19版本都可以
三、解决方案:
在LoginUser实体类上添加@JsonIgnoreProperties注解,让redis序列化的时候忽略这些字段。
fastjson的RedisConfig配置
import com.alibaba.fastjson.support.spring.GenericFastJsonRedisSerializer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
/**
* 自己定义了一个redisTemplate
*
* @param redisConnectionFactory
* @return
*/
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
// 为了自己开发方便,一般使用<String,Object>
RedisTemplate<String, Object> template = new RedisTemplate();
template.setConnectionFactory(redisConnectionFactory);
// json的序列化配置
GenericFastJsonRedisSerializer serializer = new GenericFastJsonRedisSerializer();
template.setDefaultSerializer(serializer);
// string的序列化配置
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key采用string序列化方式
template.setKeySerializer(stringRedisSerializer);
// hash的key也采用string的序列化方式
template.setHashKeySerializer(stringRedisSerializer);
// value采用FastJson的序列化方式
template.setValueSerializer(serializer);
// hash的value也采用FastJson的序列化方式
template.setHashValueSerializer(serializer);
template.afterPropertiesSet();
return template;
}
}
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.49</version>
</dependency>