您好,欢迎来到爱玩科技网。
搜索
您的当前位置:首页springSecurity+redis反序列化失败--problem deserializing ‘setterless‘ property (“authorities“)

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":"150619947","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":"150619947","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数据这个方法就不可以行。所以我还是建议第一种方法。可以在保证数据完整行的前提下完美解决问题。

搞定

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

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- aiwanbo.com 版权所有 赣ICP备2024042808号-3

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务