报错内容:

Caused by: com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize value of type `org.springframework.security.core.authority.SimpleGrantedAuthority` from Array value (token `JsonToken.START_ARRAY`)

redis里存的对应的json格式:

 "authorities": [
            "java.util.ArrayList",
            [
                [
                    "org.springframework.security.core.authority.SimpleGrantedAuthority",
                    {
                        "role": "admin",
                        "authority": "admin"
                    }
                ],
                [
                    "org.springframework.security.core.authority.SimpleGrantedAuthority",
                    {
                        "role": "common",
                        "authority": "common"
                    }
                ]
            ]
        ],

原因: 字符串反序列化是,需要对应的对象有空参构造函数

而SimpleGrantedAuthority是只有有参构造,并且被final修饰不能继承重写

解决办法:

需要对该类进行手动进行反序列化

步骤:

第一步:自定义的反序列化器

public class SimpleGrantedAuthorityDeserializer extends StdDeserializer<SimpleGrantedAuthority> {
    public SimpleGrantedAuthorityDeserializer() {
        super(SimpleGrantedAuthority.class);
    }
    @Override
    public SimpleGrantedAuthority deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
        JsonNode jsonNode = p.getCodec().readTree(p);
         Iterator<JsonNode> elements = jsonNode.elements();
        while (elements.hasNext()) {
            JsonNode next = elements.next();
            JsonNode authority = next.get("authority");
            if(ObjectUtils.isEmpty(authority)){
                continue;
            }

             return new SimpleGrantedAuthority(authority.asText());
        }
        return  null;

    }
}

第二步:将构造器加入到ObjectMapper 中

@Bean
@ConditionalOnMissingBean(RedisSerializer.class)
@SuppressWarnings("all")
public RedisSerializer<Object> serializer( ObjectMapper objectMapper) {
   // 使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
   Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
   // 指定要序列化的域,field,get和set,以及修饰符范围,ANY是都有包括private和public
   objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
   // 指定序列化输入的类型,类必须是非final修饰的,final修饰的类,比如String,Integer等会跑出异常
   objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL);
   //解决jackson2无法反序列化SimpleGrantedAuthority问题(原因是没有空参构造)
   objectMapper.registerModule(new SimpleModule().addDeserializer(
         SimpleGrantedAuthority.class, new SimpleGrantedAuthorityDeserializer()));

   jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
   return jackson2JsonRedisSerializer;
}

注意: ObjectMapper 不能new ,只能导入全局的,否则其他位置不生效

其他没有空参够够也会出现该问题,也需要注意

Logo

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

更多推荐