【问题标题】:Deserialize into another class - Spring data redis反序列化成另一个类——Spring data redis
【发布时间】:2020-01-06 10:43:36
【问题描述】:

使用 Spring Data Redis 我序列化一个对象并将其存储到 Redis 中。序列化策略为Jackson2JsonRedisSerializer。所以,假设我的 bean 是 Sample.java 有一些属性 prop1, prop2 下面是它是如何添加到缓存中的

\xAC\xED\x00\x05sr\x00'com.main.model.Sample\x90\x91\xFB4\xDD\x9D\xE1\xBB\x02\x00\x11J\x00\x0Bprop1J\x00\x0Aprop2J

正如我们所见,对象类型信息Sample 也与其完全限定名称一起存储。

现在有多个服务通过反序列化和更新它写回缓存来处理这个条目。 (各种服务中的模型/bean 具有不同的完全限定名称)

当不同的服务尝试反序列化它失败时会出现问题ClassNotFoundException

    org.springframework.data.redis.serializer.SerializationException:         
       Cannot serialize; nested exception is 
       org.springframework.core.serializer.support.SerializationFailedException: 
       Failed to deserialize object type; 
       nested exception is java.lang.ClassNotFoundException: com.xyz.model.BasicSample

这是一个示例

服务 1

    @Override
    @Cacheable(value = "sample", key = "{ #sample.sampleId }", unless = "#result == null")
    public Sample fetchSample(Sample sample) {...}

服务 2

    @Override
    @Cacheable(value = "sample", key = "{ #sample.sampleId }", unless = "#result == null")
    public BasicSample fetchBasicSample(BasicSample sample) {...}

有没有办法

  • 停止存储此信息

  • 在反序列化时忽略这个

  • 一种反序列化为具有相同属性的不同类对象的方法

【问题讨论】:

  • 查看存储在 Redis 中的示例数据这看起来不像是 Jackson 序列化,而是更像是默认的 jdk 序列化。你能检查一下你的RedisCacheConfiguration 应该有类似...serializeValuesWith(SerializationPair.fromSerializer(RedisSerializer.json()))
  • @ChristophStrobl 对! Spring Data Redis 使用的默认序列化器是Jackson2JsonRedisSerializer,它在内部使用 jdk 序列化。
  • 您有要运行的样本吗? Jackson 序列化程序直接使用ObjectMapper.writeValuesAsBytes。因此,Redis 中的条目应该是纯 JSON,例如 {"@class":"com.xyz.model.Sample","firstame":"calmity",... 你有运行 sn-p/gist/repo 吗?

标签: serialization json-deserialization spring-data-redis


【解决方案1】:

我只是在同一个问题上花了半天时间,所以把答案留给后代:

通常,Spring Data Redis 将使用完整的类名作为 _class 键,但开发人员可以使用 @TypeAlias("someAlias") 注释对其进行自定义。这将覆盖 _class 字段。

因此您可以将这两个类定义为:

package com.example.service1;

import org.springframework.data.annotation.TypeAlias;
import org.springframework.data.redis.core.RedisHash;
import org.springframework.data.redis.core.index.Indexed;

@RedisHash(value = "sample")
@TypeAlias("SampleType")
public class Sample {
    @Indexed
    int id;

    String name;
    ...
}
package com.example.service2;

import org.springframework.data.annotation.TypeAlias;
import org.springframework.data.redis.core.RedisHash;
import org.springframework.data.redis.core.index.Indexed;

@RedisHash(value = "sample")
@TypeAlias("SampleType")
public class Sample {
    @Indexed
    int id;

    String name;
    ...
}

现在 redis 对象将独立于类包名称进行反序列化。

Link to the relevant documentation for more info

【讨论】:

  • 感谢您的努力 :) 会试一试。
猜你喜欢
  • 2018-10-06
  • 2017-07-21
  • 2020-11-03
  • 1970-01-01
  • 1970-01-01
  • 2018-09-23
  • 2017-12-23
  • 1970-01-01
  • 2013-02-25
相关资源
最近更新 更多