Shiro和Redis结合缓存中反序列化出现问题,求解决

脐橙_ 2019-06-17 08:59:06
该Demo是SSM+Shiro+JWT+Redis整合。
在Shiro+Redis整合中,将授权以及认证两者缓存存储到Redis中,但是出现认证反序列化丢失数据问题,而授权反序列化正常。
测试如下:
使用JdkSerializationRedisSerializer序列化器,进去的数据为二进制,认证和授权序列化以及反序列化都正常,数据内容如下:

使用:Jackson2JsonRedisSerializer出现问题:
java.lang.ClassCastException:java.util.LinkedHashMap无法强制转换为org.apache.shiro.authc.AuthenticationInfo,且数据如下

使用:GenericFastJsonRedisSerializer出现问题:
java.lang.IllegalStateException: Principals returned from securityManager.login( token ) returned a null or empty value. This value must be non null and populated with one or more elements. 数据如下:


这些问题都只发生在认证类反序列上!!
本人,直接使用RedisTemplate设置序列化器,且直接调用Hset 和 Hget方法进行存储和获取,并无其他操作!
使用JdkSerializationRedisSerializer序列化器二进制数据无法查看,
用Jackson2JsonRedisSerializer和GenericFastJsonRedisSerializer皆为JSON数据可看,但问题出现认证反序列化!

...全文
1087 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jinbin_Z 2020-12-18
  • 打赏
  • 举报
回复
是不是这些对象的某些字段是 transient 修饰的
脐橙_ 2020-05-16
  • 打赏
  • 举报
回复
引用 6 楼 平心卡卡 的回复:
主要是序列化的问题,key可以使用任何序列化器,value建议使用jdk的序列化,

/**
 * 重写序列化 序列化为字节码
 *
 * @author hyp
 */
public class MyRedisSerializer implements RedisSerializer<Object> {

    @Override
    public byte[] serialize(Object o) throws SerializationException {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream objOut;
        try {
            objOut = new ObjectOutputStream(byteOut);
            objOut.writeObject(o);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return byteOut.toByteArray();
    }

    @Override
    public Object deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null) {
            return null;
        }
        ByteArrayInputStream byteIn = new ByteArrayInputStream(bytes);
        ObjectInputStream objIn;
        Object obj;
        try {
            objIn = new ObjectInputStream(byteIn);
            obj = objIn.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }
        return obj;
    }


}

 @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        MyRedisSerializer myRedisSerializer = new MyRedisSerializer();
        template.setKeySerializer(stringRedisSerializer);
        template.setValueSerializer(myRedisSerializer);
        template.setHashKeySerializer(stringRedisSerializer);
        template.setHashValueSerializer(myRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
以前有试过,当出现复杂对象则不行,我记得是集合嵌套和一些类的子类并没有提供无参构造函数的情况下JDK也是无法解决
平心卡卡 2020-04-02
  • 打赏
  • 举报
回复
主要是序列化的问题,key可以使用任何序列化器,value建议使用jdk的序列化,

/**
 * 重写序列化 序列化为字节码
 *
 * @author hyp
 */
public class MyRedisSerializer implements RedisSerializer<Object> {

    @Override
    public byte[] serialize(Object o) throws SerializationException {
        ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
        ObjectOutputStream objOut;
        try {
            objOut = new ObjectOutputStream(byteOut);
            objOut.writeObject(o);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return byteOut.toByteArray();
    }

    @Override
    public Object deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null) {
            return null;
        }
        ByteArrayInputStream byteIn = new ByteArrayInputStream(bytes);
        ObjectInputStream objIn;
        Object obj;
        try {
            objIn = new ObjectInputStream(byteIn);
            obj = objIn.readObject();
        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
            return null;
        }
        return obj;
    }


}

 @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(factory);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
        MyRedisSerializer myRedisSerializer = new MyRedisSerializer();
        template.setKeySerializer(stringRedisSerializer);
        template.setValueSerializer(myRedisSerializer);
        template.setHashKeySerializer(stringRedisSerializer);
        template.setHashValueSerializer(myRedisSerializer);
        template.afterPropertiesSet();
        return template;
    }
脐橙_ 2019-07-11
  • 打赏
  • 举报
回复
有人遇见相似问题或者其他的 可以私聊我 我希望学到更多和帮助更多。 wei:zhu847033093
脐橙_ 2019-07-11
  • 打赏
  • 举报
回复
引用 3 楼 haiyangyiba 的回复:
跟楼主一样也是尝试了几种序列化方式均报错了,,,最终使用gson的可以了?
对,我是使用了Gson处理的,你可以看看我的这两篇文章:https://blog.csdn.net/weixin_41123719/article/details/95210739和https://blog.csdn.net/weixin_41123719/article/details/95215860。 主要还是一些序列化器无法很好的处理复杂对象导致丢失精度或就是无法序列化,如果使用阿里巴巴的则会丢失精度,使用Gson则出现无法序列化,这个都是在没有自定义处理复杂对象前提下出现的,如果自定义了即可解决。
haiyangyiba 2019-07-10
  • 打赏
  • 举报
回复
跟楼主一样也是尝试了几种序列化方式均报错了,,,最终使用gson的可以了?
脐橙_ 2019-06-23
  • 打赏
  • 举报
回复
该问题,可以通过gson提供的序列化器依以及提供的自定义功能进行对复杂类型数据序列化和反序列化处理,数据正常。
脐橙_ 2019-06-17
  • 打赏
  • 举报
回复
恳求各位码农高手,出手相助,该认证类,尝试过将此转成JSON数据,但是解析JSON数据回对象,也是会出现丢失精度问题!!

67,513

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧