当前位置:网站首页>Redis 序列化 GenericJackson2JsonRedisSerializer和Jackson2JsonRedisSerializer的区别
Redis 序列化 GenericJackson2JsonRedisSerializer和Jackson2JsonRedisSerializer的区别
2022-07-02 06:33:00 【保护我方胖虎】
文章目录
/** * 实例化 RedisTemplate 对象 * @return */
@Bean
public RedisTemplate<String, Object> functionDomainRedisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
// key 都使用String 序列化方式
redisTemplate.setKeySerializer(stringRedisSerializer);
redisTemplate.setHashKeySerializer(stringRedisSerializer);
GenericJackson2JsonRedisSerializer genericJackson2JsonRedisSerializer = new GenericJackson2JsonRedisSerializer();
// Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
redisTemplate.setHashValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setValueSerializer(genericJackson2JsonRedisSerializer);
redisTemplate.setConnectionFactory(factory);
return redisTemplate;
}
GenericJackson2JsonRedisSerializer
GenericJackson2JsonRedisSerializer序列化时,会保存序列化的对象的完全限定名,从redis获取数据时即可直接反序列化成指定的对象
通用参数如下:
List<Student> students = new ArrayList<>();
Student xm = new Student("小明", 12);
Student ph = new Student("胖虎", 12);
students.add(xm);
students.add(ph);
(1)VALUE 存普通对象
存:
Student xm = new Student("小明", 12);
redisTemplate.opsForValue().set(xm.getName(), xm);

值中附带了实体信息
取:
Student xmCache = (Student)redisTemplate.opsForValue().get(xm.getName());
// Student(name=小明, age=12)
System.out.println(xmCache);
结论:GenericJackson2JsonRedisSerializer 序列化方式 可直接存储VALUE为对象,且从Redis获取可进行强转
(2)VALUE 存对象集合
存:
redisTemplate.opsForSet().add("students-genericJackson2JsonRedisSerializer", students);
redisTemplate.opsForValue().set("students-str", students);

值中既有实体类完全限定名又有集合类型
–

具体值中携带了实体类完全限定名
取:
List<Student> studentCache = (List<Student>) redisTemplate.opsForValue().get("students-str");
Set<Object> members = redisTemplate.opsForSet().members("students-genericJackson2JsonRedisSerializer");
// [Student(name=小明, age=12), Student(name=胖虎, age=12)]
System.out.println(studentCache);
// [Student(name=胖虎, age=12), Student(name=小明, age=12)]
System.out.println(members);
结论:GenericJackson2JsonRedisSerializer 序列化方式 可直接存储VALUE为对象集合,且从Redis获取可进行强转
(3)VALUE 存JSON字符串
redisTemplate.opsForValue().set(ph.getName(), JSON.toJSONString(ph));
存:

无@class字段,且jSON字符串中含有转义符
取:
Object o = redisTemplate.opsForValue().get(ph.getName());
System.out.println(o);

注意点:因为这里存是JSON字符串,所以取数据时候,也无法直接强制转为Student对象,我们需要手动调用方法,将JSON字符串转换为JAVA对象
redisTemplate.opsForValue().set(ph.getName(), JSON.toJSONString(ph));
Object o = redisTemplate.opsForValue().get(ph.getName());
// Student(name=胖虎, age=12)
System.out.println(o == null ? null : JSON.parseObject(o.toString(), Student.class));
结论:GenericJackson2JsonRedisSerializer 序列化方式 可直接存储VALUE为JSON字符串形式,且从Redis获取后不可进行强转,需要将结果转为字符串,再将JSON字符串转为自己需要的对象或对象集合
(4)管道Pipelined存数据
存:
List<Student> students = new ArrayList<>();
Student xm = new Student("小明", 12); Student ph = new Student("胖虎", 12);
students.add(xm); students.add(ph);
redisTemplate.executePipelined((RedisCallback) conn -> {
students.forEach(s -> conn.set(s.getName().getBytes(), JSON.toJSONString(s).getBytes()));
return null;
});


管道操作的数据并没有@class 实体类属性,实体类完全限定名丢失,那么这个时候还能否获取数据呢?
答案是不能
取:
取完直接强转:
Student xmCache = (Student)redisTemplate.opsForValue().get(xm.getName());
System.out.println(xmCache);

GET取完不强转
Object xmCache = redisTemplate.opsForValue().get(xm.getName());
System.out.println(xmCache);

MGET 批量获取
List<Object> objectList = redisTemplate.opsForValue().multiGet(students.stream().map(Student::getName).collect(Collectors.toList()));
System.out.println(objectList);
return objectList;

ERROR 16400 — [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property ‘@class’
at [Source: (byte[])"{“age”:12,“name”:“小明”}"; line: 1, column: 26]; nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property ‘@class’
at [Source: (byte[])"{“age”:12,“name”:“小明”}"; line: 1, column: 26]] with root cause
翻译过来的意思是:无法读取 JSON:尝试解析 [简单类型,类 java.lang.Object] 的子类型时缺少类型 ID:缺少类型 id 属性“@class”
结论: 使用GenericJackson2JsonRedisSerializer 序列化进行管道操作后,实体类@class属性会丢失,再次从redis获取数据将无法成功反序列化
Jackson2JsonRedisSerializer
通用参数如下:
List<Student> students = new ArrayList<>();
Student ys = new Student("亚索", 12);
Student mw = new Student("蛮王", 12);
students.add(ys);
students.add(mw);
(1)VALUE 存普通对象
存:
redisTemplate.opsForValue().set(ys.getName(), ys);
redisTemplate.opsForValue().set(mw.getName(), mw);

取:
Student ysCache = (Student)redisTemplate.opsForValue().get(ys.getName());
System.out.println(ysCache);
发现报错:java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.leilei.entity.Student

断点调试:获取的ysCache 实际是一个LinkedHashMap
Object ysCache = redisTemplate.opsForValue().get(ys.getName());
System.out.println(ysCache);

存对象集合结果一样…
redisTemplate.opsForValue().set("lol", students);
Object lolCache = redisTemplate.opsForValue().get("lol");
System.out.println(lolCache);

解决办法:
Jackson2JsonRedisSerializer序列化时 存数据都采用JSON字符串方式,然后取数据时也不直接将结果强转,而是使用JSON反序列化 将JSON字符串反序列化为java对象或集合
请看示例二:VALUE 存JSON字符串
结论:Jackson2JsonRedisSerializer序列化方式,如VALUE直接存对象或者对象集合,获取时结果为LinkedHashMap,无法直接使用JDK强转方法转为对象或对象集合,需借助工具进行转换为实体与实体集合
(2)VALUE 存JSON字符串
存:
redisTemplate.opsForValue().set(ys.getName(), JSON.toJSONString(ys));
redisTemplate.opsForValue().set(mw.getName(), JSON.toJSONString(mw));

–

字符串中有转义字符
取:
Object ysCache = redisTemplate.opsForValue().get(ys.getName());
// Student(name=亚索, age=122)
System.out.println(ysCache == null ? null : JSON.parseObject(ysCache.toString(), Student.class));
List<Object> cacheList = redisTemplate.opsForValue().multiGet(students.stream().map(Student::getName).collect(Collectors.toList()));
List<Student> studentList = cacheList.stream().filter(Objects::nonNull).map(Object::toString).map(x -> JSON.parseObject(x, Student.class)).collect(Collectors.toList());
// [Student(name=亚索, age=122), Student(name=蛮王, age=234)]
System.out.println(studentList);
结论:Jackson2JsonRedisSerializer序列化方式,VALUE存JSON字符串时,取值也为JSON字符串,需借助JSON工具进行转换为实体类或实体集合
(3)管道Pipelined存数据
存:
redisTemplate.executePipelined((RedisCallback<String>) conn -> {
students.forEach(s -> conn.set(s.getName().getBytes(), JSON.toJSONString(s).getBytes()));
return null;
});

–

取:
获取管道存储的值变为了LinkedHashMap

因为我们需要将map转为java对象,我这里采用的是先转JSON字符串方式


List<Object> cacheList = redisTemplate.opsForValue().multiGet(students.stream().map(Student::getName).collect(Collectors.toList()));
if (CollectionUtils.isEmpty(cacheList)) {
return null;
}
List<Student> studentList = cacheList.stream().filter(Objects::nonNull).map(JSON::toJSONString).map(x -> JSON.parseObject(x, Student.class)).collect(Collectors.toList());
// [Student(name=亚索, age=122), Student(name=蛮王, age=234)]
System.out.println(studentList);
结论:Jackson2JsonRedisSerializer 序列化方式,且使用管道操作后,获取的值也是一个linkedHashMap,需借助工具才可将值反序列化为实体对象或实体对象集合
边栏推荐
- Machine learning practice: is Mermaid a love movie or an action movie? KNN announces the answer
- Essay: RGB image color separation (with code)
- [go practical basis] how to install and use gin
- Data type case of machine learning -- using data to distinguish men and women based on Naive Bayesian method
- Solution to amq4036 error in remote connection to IBM MQ
- [staff] time mark and note duration (staff time mark | full note rest | half note rest | quarter note rest | eighth note rest | sixteenth note rest | thirty second note rest)
- AMQ6126问题解决思路
- Webflux responsive programming
- Find the node with the smallest value range in the linked list and move it to the front of the linked list
- Image transformation, transpose
猜你喜欢

别找了,Chrome浏览器必装插件都在这了

十年开发经验的程序员告诉你,你还缺少哪些核心竞争力?

Knowledge points are very detailed (code is annotated) number structure (C language) -- Chapter 3, stack and queue

Shengshihaotong and Guoao (Shenzhen) new energy Co., Ltd. build the charging pile industry chain
![[go practical basis] gin efficient artifact, how to bind parameters to structures](/img/c4/44b3bda826bd20757cc5afcc5d26a9.png)
[go practical basis] gin efficient artifact, how to bind parameters to structures
![[staff] time mark and note duration (staff time mark | full note rest | half note rest | quarter note rest | eighth note rest | sixteenth note rest | thirty second note rest)](/img/7f/2cd789339237b7a881bfed7b7545a9.jpg)
[staff] time mark and note duration (staff time mark | full note rest | half note rest | quarter note rest | eighth note rest | sixteenth note rest | thirty second note rest)

Function ‘ngram‘ is not defined

Matplotlib剑客行——布局指南与多图实现(更新)

Matplotlib剑客行——初相识Matplotlib

Troubleshooting and handling of an online problem caused by redis zadd
随机推荐
Introduction to the basic concept of queue and typical application examples
Avoid breaking changes caused by modifying constructor input parameters
[go practical basis] how to set the route in gin
微服务实战|手把手教你开发负载均衡组件
How to realize asynchronous programming in a synchronous way?
Double non undergraduate students enter the factory, while I am still quietly climbing trees at the bottom (Part 1)
Gocv split color channel
Micro service practice | introduction and practice of zuul, a micro service gateway
I've taken it. MySQL table 500W rows, but someone doesn't partition it?
【Go实战基础】gin 如何绑定与使用 url 参数
Leetcode sword finger offer brush questions - day 22
CSDN Q & A_ Evaluation
Microservice practice | teach you to develop load balancing components hand in hand
C language implementation of mine sweeping game
概率还不会的快看过来《统计学习方法》——第四章、朴素贝叶斯法
西瓜书--第六章.支持向量机(SVM)
一篇详解带你再次重现《统计学习方法》——第二章、感知机模型
gocv opencv exit status 3221225785
[go practical basis] how can gin get the request parameters of get and post
[go practical basis] how to customize and use a middleware in gin