【问题标题】:Spring Session Redis fails to deserialize with ClassNotFoundExceptionSpring Session Redis 无法使用 ClassNotFoundException 反序列化
【发布时间】:2017-02-15 22:10:31
【问题描述】:
org.springframework.data.redis.serializer.SerializationException: Cannot deserialize; 
  nested exception is org.springframework.core.serializer.support.SerializationFailedException:

Failed to deserialize payload. Is the byte array a result of corresponding serialization for DefaultDeserializer?; 
  nested exception is org.springframework.core.NestedIOException:

Failed to deserialize object type; 
  nested exception is java.lang.ClassNotFoundException: com.foo.user.model.CurrentUser

我有两个典型的 Spring Boot 应用程序,它们共享一个用于会话状态的 Redis 实例。尝试登录我的应用程序时会立即发生上述错误。

我不太确定这里发生了什么 - 两个应用程序对适用的用户模型和 Spring 依赖项使用相同的库和版本。值得CurrentUser 扩展org.springframework.security.core.userdetails.User,它本身就是Serializable

我已经重新启动了我的 Redis 实例,以为有些东西变得很时髦,但事实并非如此。我会展示我已经尝试过的东西,但主要是确保我的工件正确构建并重新启动应用程序和 Redis 服务器,并稍微玩弄Serializable

为什么我会看到这个?

【问题讨论】:

  • CurrentUser 的所有成员都可以序列化吗?
  • 几个问题:Redis 配置(更具体地说是序列化部分)在两个应用程序中是否相同?如果我理解正确CurrentUser 位于两个应用程序之间共享的外部库中?你在使用 Boot DevTools 吗?重现问题或至少两个应用程序的相关配置部分的示例将很有用。
  • 士力架 - 是的。 Vedran - 哪些信息对您有帮助?
  • @BrandonV 你能解决这个问题吗?我面临同样的问题:/
  • @varunkr 我确实解决了这个问题,但不幸的是,我不记得做了什么。对不起。

标签: java spring spring-boot redis spring-session


【解决方案1】:

当发送服务器与接收服务器不同时,您很可能会收到此错误(单独的服务器)

问题来自 ValueSerializer

为避免此问题,请使用 Jackson2JsonRedisSerializer 作为发送方和接收方的值序列化器

    @Bean
    protected RedisTemplate<String, Object> redisTemplate() {
      final RedisTemplate<String, Object> template = new RedisTemplate<>();
      template.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
      .........
      return template;
    }

这样序列化过程将基于 json 而不是基于类

【讨论】:

    【解决方案2】:

    异常显示“无法反序列化” 看起来您在 Redis 中存储了一些东西,现在无法反序列化。 可能你同时改变了serialVersionUID?

    我看到你重新启动了 Redis,但可能是条目被保留并在重新启动后幸存下来?

    【讨论】:

    • 我会检查的。 AWS Elasticache 完全有可能允许数据在重启后仍然存在。对象确实发生了变化,但我希望重新启动会刷新商店。
    • 不走运。重新创建集群和同样的问题。还有其他想法吗?
    • 检查您使用的编解码器/序列化是否与反序列化时使用的不同。
    【解决方案3】:

    当您将数据存储到 redis 时,只需将其类型转换为 Object 类,当您从 redis 取回数据时,只需将其作为 Object 获取。然后将其类型转换为您拥有的任何 POJO 类。它在我的情况下有效。 存储时->

    redisTemplate.opsForHash().put("<YOUR-key>", "<YOUR-field>",(Object) empList);
    

    获取时->

    Object employeeFromCache=operation.get("<YOUR-key>", "<YOUR-field>");
            employees=(List<Employee>)employeeFromCache;
    

    【讨论】:

      猜你喜欢
      • 2016-09-09
      • 2016-11-26
      • 1970-01-01
      • 2018-10-06
      • 2021-02-08
      • 1970-01-01
      • 2017-11-02
      • 2021-12-14
      • 2020-11-03
      相关资源
      最近更新 更多