Redis和spring整合
Jackson2JsonRedisSerializer 和 ObjectMapper 结合使用的核心目的是 定制 JSON 序列化和反序列化的行为,特别是处理复杂对象结构、日期格式、字段过滤和多态类型。让我详细解释它们的协作方式和典型应用场景。一、核心协作机制
-
Jackson2JsonRedisSerializer- 负责将 Java 对象序列化为 Redis 存储的 JSON 字符串,以及将 JSON 字符串反序列化为 Java 对象。
- 默认使用 Jackson 的默认
ObjectMapper配置。
-
ObjectMapper- Jackson 的核心组件,控制 JSON 序列化和反序列化的具体规则(如日期格式、字段过滤、类型信息等)。
- 通过自定义
ObjectMapper,可以精细调整Jackson2JsonRedisSerializer的行为。
二、典型应用场景
1. 自定义日期格式
默认情况下,Jackson 会将
Date 序列化为时间戳。通过自定义 ObjectMapper,可以指定日期格式:java
ObjectMapper mapper = new ObjectMapper();
mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd"));
Jackson2JsonRedisSerializer<User> serializer = new Jackson2JsonRedisSerializer<>(User.class);
serializer.setObjectMapper(mapper);
2. 过滤敏感字段
使用
@JsonIgnore 注解或配置 ObjectMapper 来排除不需要序列化的字段:java
public class User {
private String id;
private String name;
@JsonIgnore // 不序列化该字段
private String password;
}
// 或者通过 ObjectMapper 配置
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY);
mapper.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE);
3. 处理多态对象(有限支持)
虽然
Jackson2JsonRedisSerializer 不自动支持多态,但可以通过 @JsonTypeInfo 注解在基类上指定类型信息:java
@JsonTypeInfo(
use = JsonTypeInfo.Id.NAME,
include = JsonTypeInfo.As.PROPERTY,
property = "type"
)
@JsonSubTypes({
@JsonSubTypes.Type(value = Dog.class, name = "dog"),
@JsonSubTypes.Type(value = Cat.class, name = "cat")
})
public interface Animal {
String getName();
}
// 配置序列化器
Jackson2JsonRedisSerializer<Animal> serializer = new Jackson2JsonRedisSerializer<>(Animal.class);
4. 处理未知属性
配置
ObjectMapper 忽略 JSON 中存在但 Java 对象中没有的字段:java
ObjectMapper mapper = new ObjectMapper();
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Jackson2JsonRedisSerializer<User> serializer = new Jackson2JsonRedisSerializer<>(User.class);
serializer.setObjectMapper(mapper);
三、完整配置示例
以下是一个结合
Jackson2JsonRedisSerializer 和自定义 ObjectMapper 的 RedisTemplate 配置:java
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
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.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, User> redisTemplate(RedisConnectionFactory factory) {
RedisTemplate<String, User> template = new RedisTemplate<>();
template.setConnectionFactory(factory);
// 1. 创建自定义 ObjectMapper
ObjectMapper mapper = new ObjectMapper();
// 2. 配置日期时间模块(支持 Java 8 的 LocalDateTime 等)
mapper.registerModule(new JavaTimeModule());
mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
// 3. 忽略未知属性
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
// 4. 创建序列化器并设置 ObjectMapper
Jackson2JsonRedisSerializer<User> serializer = new Jackson2JsonRedisSerializer<>(User.class);
serializer.setObjectMapper(mapper);
// 5. 配置 RedisTemplate
template.setKeySerializer(RedisSerializer.string());
template.setValueSerializer(serializer);
template.setHashKeySerializer(RedisSerializer.string());
template.setHashValueSerializer(serializer);
return template;
}
}
四、与 GenericJackson2JsonRedisSerializer 的对比
| 特性 | Jackson2JsonRedisSerializer | GenericJackson2JsonRedisSerializer |
|---|---|---|
| 类型信息 | 需通过 @JsonTypeInfo 显式指定 |
自动添加 @class 字段 |
| 目标类型 | 构造时必须指定(如 User.class) |
通用(无需指定目标类型) |
| 多态支持 | 需手动配置注解 | 自动支持(通过类型信息) |
| JSON 兼容性 | 更简洁,适合与其他系统共享 | 含 Spring 特定的 @class 字段 |
五、总结
- 结合使用的价值:通过自定义
ObjectMapper,可以灵活控制Jackson2JsonRedisSerializer的序列化和反序列化规则,满足复杂场景需求。 - 适用场景:当你需要处理特定格式(如日期)、过滤字段、或在有限范围内支持多态时,这种组合非常有用。
- 注意事项:
Jackson2JsonRedisSerializer仍需明确目标类型,不适合存储多种实现类的接口类型(如List<Animal>),此时应使用GenericJackson2JsonRedisSerializer。
浙公网安备 33010602011771号