一、问题描述

整合SpringSecurity时,

  1. 认证通过后把LoginUser信息存储到redis缓存中;
  1. 校验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)

二、原因分析:

  1. 整合SpringSecurity时,我们自己定义的LoginUser实体类需要继承SpringSecurity的UserDetails接口,实现其中的方法。
  1. 认证通过后把LoginUser信息存储到redis缓存中,会把接口实现类中的一些类变量序列化到redis中。
  1. 校验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>
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐