gpt4 book ai didi

json - RedisTemplate 哈希值序列化器用于具有多种类型的嵌套对象

转载 作者:IT王子 更新时间:2023-10-29 06:00:48 27 4
gpt4 key购买 nike

我正在尝试使用 Redis 为我的实体存储一些缓存数据,例如,它内部有不同类型的字段,

public class Job {
private String id;
private Date createTime; //Long
private String submitterName;
private JobDefinition jobDef; //Another class
}

有更多的字段,由于有几个字段比其他字段更新更频繁,我决定将这个作业保存为Redis中的Hashmap,每个字段作为一个键。这里像 jobDef 这样的嵌套对象并不重要,所以我使用 Jackson2JsonRedisSerializer 作为 hashValueSerializer 用于 RedisTemplate jobDef obj 将被序列化为一个长 JSON 字符串,这对我来说完全没问题。

但我不知道如何有效地反序列化整个 job 对象从 Redis 返回。我设置为反序列化器的类型类似于 Jackson2JsonRedisSerializer(Map.class) 但它在反序列化 String 键和值时会报错。

这是否是 RedisTemplate 的无效用法,或者我应该如何为它配置我的序列化程序?

编辑:添加更多代码细节,

    @Autowired
private StringRedisTemplate redisTemplate; //Here I'm using a String template as I need to use the same redisTemplate for some key-value/list operations too

Map jobHash= new ObjectMapper().convertValue(job, Map.class);

redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer(Map.class));

redisTemplate.opsForHash().putAll("job:"+job.getId(), jobHash); //After this the job hash shows up in Redis as I expected, while the jobDef member is serialized and saved as a JSON string

Map jobMap = redisTemplate.opsForHash().entries("job:" + job.getId()); //But this won't work as it'll throw exception complaining cannot deserialize a String value to Map. But when I set Jackson2JsonRedisSerializer(String.class) it throws exception that cannot resolve the byte code

第二次编辑:

如果在 RedisTemplate 中使用 JdkSerializationRedisSerializer 作为 HashValueSerializer,那么反序列化工作正常,但是使用这个反序列化的缺点是存储在 Redis 中的值与人类可读的字符串不同使用 Jackson2JsonRedisSerializer 时的值。

最佳答案

Jackson2JsonRedisSerializer 不将映射信息包含到实际的哈希结构中。生成的 Redis HASH 结果如下:

127.0.0.1:6379> hgetall job:1
1) "id"
2) "\"1\""
3) "createTime"
4) "1455778716799"
5) "submitterName"
6) "\"Jon Snow\""
7) "jobDef"
8) "{\"def\":\"nightwatch\"}"

ObjectMapperJobDefinition 条目生成一个 LinkedHashMap,由于类型未知,无法反序列化。

使用 GenericJackson2JsonRedisSerializer 包含类型信息,因此生成的 Redis HASH 如下所示:

127.0.0.1:6379> hgetall job:1
1) "id"
2) "\"1\""
...
7) "jobDef"
8) "{\"@class\":\"java.util.LinkedHashMap\",\"def\":\"nightwatch\"}"

这允许正确反序列化值。

另一种方法是使用特定的HashValueSerializer,而是使用DecoratingStringHashMapperStringRedisTemplate .

DecoratingStringHashMapper mapper = new DecoratingStringHashMapper<Job>(
new JacksonHashMapper<Job>(Job.class));

template.opsForHash().putAll("job:" + job.id, mapper.toHash(job));
Map jobMap = template.opsForHash().entries("job:" + job.id);

DecoratingStringHashMapper 将生成如下 Redis 哈希:

127.0.0.1:6379> hgetall job:1
1) "id"
2) "1"
3) "createTime"
4) "1455780810643"
5) "submitterName"
6) "Jon Snow"
7) "jobDef"
8) "{def=nightwatch}"

不幸的是没有Jackson2HashMapper。请投票给DATAREDIS-423并帮助我们确定优先顺序。

关于json - RedisTemplate 哈希值序列化器用于具有多种类型的嵌套对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35444692/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com