redis 序列化
2021/10/21 19:11:43
本文主要是介绍redis 序列化,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
前言
redis版本的变更对于spring封装的java API影响不大,集成也没什么难度。重要的是序列化方面需要注意。
本次 spring-data-redis版本为2.5.5
序列化
spring-data-redis的序列化统统派生于 org.springframework.data.redis.serializer.RedisSerializer
接口
最终入redis都会是字节数组,但是不同的序列化器会进行不同的序列化策略,有的先转换jackson对象,再将该对象以字节数组的方式入redis。
- ByteArrayRedisSerializer 对象 <——> 字节数组
- GenericJackson2JsonRedisSerializer 对象 <——> 通用jackson2Json对象
- GenericToStringSerializer 对象 <——> 字符串
- Jackson2JsonRedisSerializer 对象 <——> jackson2Json对象
- JdkSerializationRedisSerializer 对象 <——> 字节数组
- OxmSerializer 对象 <——> Spring's O/X Mapping
- StringRedisSerializer 对象 <——> 字符串
着重说三类
字符串序列化
- StringRedisSerializer
- GenericToStringSerializer
两个都是字符串序列化使用,只是GenericToStringSerializer多了一个转换器操作。
// GenericToStringSerializer先将对象通过传唤器转换成字符串,再(指定编码)获得字节数组 @Override public T deserialize(@Nullable byte[] bytes) { if (bytes == null) { return null; } String string = new String(bytes, charset); return converter.convert(string, type); } @Override public byte[] serialize(@Nullable T object) { if (object == null) { return null; } String string = converter.convert(object, String.class); return string.getBytes(charset); }
// StringRedisSerializer直接进行字符串与字节数组(指定编码)转换操作,charset默认默认为UTF8 */ @Override public String deserialize(@Nullable byte[] bytes) { return (bytes == null ? null : new String(bytes, charset)); } /* * (non-Javadoc) * @see org.springframework.data.redis.serializer.RedisSerializer#serialize(java.lang.Object) */ @Override public byte[] serialize(@Nullable String string) { return (string == null ? null : string.getBytes(charset)); }
JSON序列化
有时候我们想直接在redis相关的UI界面(RDM等)直观的看到数据,而我们的数组通常都是对象的形式存在,此时我们就可以使用先将原始java对象转为json对象,再由json对象转字节数组入redis
- Jackson2JsonRedisSerializer
- GenericJackson2JsonRedisSerializer
两者的区别:
GenericJackson2JsonRedisSerializer
有个构造方法可以使用给定名称为默认类型配置ObjectMapper,或者配置默认的ObjectMapper
;
Jackson2JsonRedisSerializer
不管ObjectMapper
怎么来的,只管用。
两种方式最终的操作都是ObejctMapper对象,只要ObjectMapper对象一样,两者没有任何区别
此处由于GenericJackson2JsonRedisSerializer
构造方法里面使用默认ObjectMapper
的方式调用了过时方法,所以下文案例将采用Jackson2JsonRedisSerializer
JDK序列化
- JdkSerializationRedisSerializer
不配置序列化方式,则会采用的默认序列化规则,上面的两种json序列化方式有个问题,就是反序列化的时候强依赖于对象是否由标准的构造方法,对于某些框架对象而言,都是有特定的流程场景使用的,例如Spring Securit的Authorization对象。如果使用上面的json序列化方式的话,会反序列化出错。
org.springframework.data.redis.serializer.SerializationException: Could not read JSON: Cannot construct instance of `org.springframework.security.authentication.UsernamePasswordAuthenticationToken` (no Creators, like default constructor, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
此时我们就可以使用JDK序列化,不便的是我们无法直接在redis UI界面直观的看数据值。
附上本人的redis配置
package com.example.demo; import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.JsonTypeInfo; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; /** * @author ListJiang * @since 2021/10/21 * description redis配置 */ @Configuration public class RedisConfig { @Bean public RedisTemplate redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) { // RedisTemplate RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>(); // 序列化配置 RedisSerializer<Object> jdkSerializer = jdkSerializer(); RedisSerializer<String> stringSerializer = new StringRedisSerializer(); // String redisTemplate.setKeySerializer(stringSerializer); redisTemplate.setValueSerializer(jdkSerializer); // Hash redisTemplate.setHashKeySerializer(stringSerializer); redisTemplate.setHashValueSerializer(jdkSerializer); // 连接工厂配置 redisTemplate.setConnectionFactory(lettuceConnectionFactory); redisTemplate.afterPropertiesSet(); return redisTemplate; } private Jackson2JsonRedisSerializer jackson2JsonSerializer() { Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); ObjectMapper objectMapper = new ObjectMapper(); objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); jackson2JsonRedisSerializer.setObjectMapper(objectMapper); return jackson2JsonRedisSerializer; } private JdkSerializationRedisSerializer jdkSerializer() { return new JdkSerializationRedisSerializer(); } }
这篇关于redis 序列化的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-08阿里云Redis项目实战入门教程
- 2024-11-08阿里云Redis资料:新手入门与初级使用指南
- 2024-11-08阿里云Redis教程:新手入门及实用指南
- 2024-11-07阿里云Redis学习入门:新手必读指南
- 2024-11-07阿里云Redis学习入门:从零开始的操作指南
- 2024-11-07阿里云Redis学习:初学者指南
- 2024-11-06阿里云Redis入门教程:轻松搭建与使用指南
- 2024-11-02Redis项目实战:新手入门教程
- 2024-10-22Redis入门教程:轻松掌握数据存储与操作
- 2024-10-22Redis缓存入门教程:快速掌握Redis缓存基础知识