本章节将介绍 RedisTemplate 类中提供的与序列化相关的方法。当我们将 Java 对象存储到 Redis 中时,需要进行序列化操作,如将 Java 对象序列化 JSON 字符串。此时,Redis 中保存的内容为序列化后的 JSON 字符串。
同时,如果要将序列化后的 JSON 字符串从 Redis 取出,同时要转换成存储前的 Java 对象。此时,则需要用到反序列化操作,将 JSON 字符串转换成 Java 对象。
在 Spring Data Redis 中,提供了如下几种默认的序列化器(见 org.springframework.data.redis.serializer 包):
JdkSerializationRedisSerializer 使用 jdk 序列化机制,将对象通过 objectInputstream/objectOutputstream 方法进行序列化操作,最终 Redis 中将存储字节序列,是默认的序列化策略。限制:被序列化 Class 需要实现 Serializable 接口,而且 Redis 数据库中数据很不直观,为16进制或乱码。
StringRedisSerializer 在 key 或 value 为字符串的场景中,根据指定的字符集对数据的字节序列编码成 String,是“new String(bytes, charset)”和“string.getbytes(charset)”的直接封装,是最轻量级和高效的策略。
Jackson2JsonRedisSerializer 使用 Jackson 和 Jackson Databind ObjectMapper 读取和写入 JSON 的序列化策略。此序列化器可用于绑定到类型化的 Bean 或非类型化的 HashMap 实例。注意:空对象被序列化为空数组,反之亦然。
GenericJackson2JsonRedisSerializer 使用 Jackson 实现的序列化器。使用 GenericJackson2JsonRedisSerializer 序列化时,会保存序列化的对象的包名和类名,反序列化时以这个作为标示就可以反序列化成指定的对象。
GenericToStringSerializer 将通用字符串转换为 byte[] (和反向) 序列化程序。依赖于 Spring ConversionService 将对象转换为字符串,反之亦然。使用指定的字符集 (默认情况下为 UTF-8) 将字符串转换为字节,反之亦然。注意:如果将类定义为 Spring Bean,则转换服务初始化会自动发生。不以任何特殊方式处理空值,将所有内容委托给容器。
OxmSerializer 提供了将 JavaBean 与 XML 之间的转换能力,目前可用的三方支持包括 jaxb,apache-xmlbeans。Redis 存储的数据将是 xml 工具。不过使用此策略,编程将会有些难度,而且效率最低;不建议使用。注意:需要 spring-oxm 模块的支持
其他序列化器:
GenericFastJsonRedisSerializer 由 FastJson 库实现的序列化器,将数组反序列化为 JSONArray ,查看 JSONArray类的定义就可以看出其是一种 List 集合,所以需要注意其强转的数据类型。
RedisTemplate 序列化相关的方法如下表:
方法定义 | 方法说明 |
RedisSerializer<?> getDefaultSerializer() | 获取当前模板默认的序列化对象 |
setDefaultSerializer(RedisSerializer<?> serializer) | 设置用于此模板的默认序列化程序。 |
RedisSerializer<?> getHashKeySerializer() | 返回 hashKeySerializer 序列化对象 |
void setHashKeySerializer(RedisSerializer<?> hashKeySerializer) | 设置 hashKeySerializer 序列化对象 |
RedisSerializer<?> getHashValueSerializer() | 返回 hashValueSerializer 序列化对象 |
void setHashValueSerializer(RedisSerializer<?> hashValueSerializer) | 设置 hashValueSerializer 序列化对象 |
RedisSerializer<?> getKeySerializer() | 返回当前模板使用的键序列化对象 |
void setKeySerializer(RedisSerializer<?> serializer) | 设置当前模板使用的键序列化对象 |
RedisSerializer<String> getStringSerializer() | 返回 stringSerializer 序列化对象 |
void setStringSerializer(RedisSerializer<String> stringSerializer) | 设置 stringSerializer 序列化对象 |
RedisSerializer<?> getValueSerializer() | 返回当前模板使用的值序列化对象 |
void setValueSerializer(RedisSerializer<?> serializer) | 设置当前模板使用的值序列化对象 |
本示例将介绍怎样在创建 RedisTemplate 实例时配置序列化方式,代码如下:
package com.hxstrive.redis.config; import com.alibaba.fastjson.parser.Feature; import com.alibaba.fastjson.serializer.SerializerFeature; import com.alibaba.fastjson.support.config.FastJsonConfig; import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer; import com.hxstrive.redis.entity.UserEntity; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.nio.charset.StandardCharsets; /** * Redis配置 * @author hxstrive.com 2022/2/26 */ @Configuration public class RedisConfig { @Bean public RedisTemplate<String,String> redisTemplate(RedisConnectionFactory factory) { RedisTemplate<String,String> redisTemplate = new RedisTemplate<>(); redisTemplate.setConnectionFactory(factory); // 设置键序列化方式 redisTemplate.setKeySerializer(new StringRedisSerializer()); // 设置简单类型值的序列化方式 redisTemplate.setValueSerializer(new StringRedisSerializer()); // 设置 hash 类型键的序列化方式 redisTemplate.setHashKeySerializer(new StringRedisSerializer()); // 设置 hash 类型值的序列化方式 redisTemplate.setHashValueSerializer(new StringRedisSerializer()); // 设置默认序列化方式 redisTemplate.setDefaultSerializer(new StringRedisSerializer()); redisTemplate.afterPropertiesSet(); return redisTemplate; } }