springSecurity+redis反序列化失败--problem deserializing ‘setterless‘ property (“authorities“)

当时用springSecurity+redis存储/读取用户信息的时候,发生报错。

报错异常

Class:class org.springframework.data.redis.serializer.SerializationException
LocalizedMessage:Could not read JSON: Problem deserializing 'setterless' property ("authorities"): 
no way to handle typed deser with setterless yet at [Source: (byte[])"{"@class":"com.jia.pojo.User"
,"id":1,"username":"root",
"paassword":"{bcrypt}$2a$10$zI7PbpjGfcsxblk50lTlr.kLW65lAAoZU6Ic.a8b1.I6V4XXk/Je.",
"phone":"15061964947","enabled":true,"accountNonExpired":true,"accountNonLocked":true,
"credentialsNonExpired":true,"roles":["java.util.ArrayList",[]],"role":null,
"authorities":["java.util.HashSet",[]]}"; line: 1, column: 314] (through reference chain: 
com.jia.pojo.User["authorities"]); nested exception is com.fasterxml.jackson.databind.exc.
InvalidDefinitionException: Problem deserializing 'setterless' property ("authorities"): 
no way to handle typed deser with setterless yet at [Source: (byte[])"
{"@class":"com.jia.pojo.User","id":1,"username":"root","password":"{bcrypt}$2a$10$zI7PbpjGfcsxblk
50lTlr.kLW65lAAoZU6Ic.a8b1.I6V4XXk/Je.",
"phone":"15061964947","enabled":true,"accountNonExpired":true,"accountNonLocked":true,
"credentialsNonExpired":true,"roles":["java.util.ArrayList",[]],"role":null,
"authorities":["java.util.HashSet",[]]}"; line: 1, column: 314] 
(through reference chain: com.jia.pojo.User["authorities"])

错误原因

这一段异常错误最主要的点在于这:

 Problem deserializing 'setterless' property ("authorities"): no way to handle typed 
 deser with setterless yet at

大概意思就是反序列化属性(“authorities”)的问题:没有setterless 方法处理输入值。

说白了就是在我们设置redis时redisConfig我们采用的是jackson,而Jackson采用的反序列化时会调用属性的set方法注入值。

RedisConfig中自定义RedisTemplate代码:

 public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
        template.setConnectionFactory(factory);
        //序列化配置
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        //om.activateDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);  过期方法,采用下面代替
        om.activateDefaultTyping(LaissezFaireSubTypeValidator.instance , ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        //String序列化
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        // key采用String的序列化方式
        template.setKeySerializer(stringRedisSerializer);
        // hash的key也采用String的序列化方式
        template.setHashKeySerializer(stringRedisSerializer);
        // value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // hash的value序列化方式采用jackson
        template.setHashValueSerializer(jackson2JsonRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }

这里是配置写入读取redis值时采用jackson进行操作。

 		// value序列化方式采用jackson
        template.setValueSerializer(jackson2JsonRedisSerializer);

但我们自定义的user类缺只有重写的getAuthorities()方法。没有getAuthorities()方法,因此jackson反序列化的时候就会失败。

在这里插入图片描述

好了,知道了原因,解决方法就简单了。

解决方法(两个方法二选一即可)

1、在实体类中,手动添加authorities属性。添加setAuthorities()方法

	@TableField(exist = false) 
    private Collection<? extends GrantedAuthority> authorities;
   public void setAuthorities(Collection<? extends GrantedAuthority> authorities) {
        this.authorities = authorities;
    }

2、在实体类中,在getAuthorities()上添加@JsonIgnore,序列化时忽略此选项。

   	@Override
    @JsonIgnore
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Set<SimpleGrantedAuthority> authorities=new HashSet<>();
        roles.forEach(role -> {
            SimpleGrantedAuthority authority = new SimpleGrantedAuthority(role.getName());
            authorities.add(authority);
        });
        return authorities;
    }

注意:如果你的前端需要authorities数据这个方法就不可以行。所以我还是建议第一种方法。可以在保证数据完整行的前提下完美解决问题。

搞定

要是解决了你的问题记得帮我点个赞哦!

评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值