关于redis使用Jackson2JsonRedisSerializer序列化,反序列化时权限模块报错的问题

在使用Jackson2JsonRedisSerializer进行Redis的序列化和反序列化时,遇到了com.fasterxml.jackson.databind.exc.MismatchedInputException错误,原因是SimpleGrantedAuthority对象没有空参数构造函数。为解决这个问题,需要自定义反序列化器并将其添加到全局ObjectMapper中,以确保序列化过程的正确执行。若其他类也存在类似问题,同样需要关注是否有空参数构造函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

报错内容:

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 ,只能导入全局的,否则其他位置不生效

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

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

DreamCatcher-qin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值