Redis和spring整合

Jackson2JsonRedisSerializer 和 ObjectMapper 结合使用的核心目的是 定制 JSON 序列化和反序列化的行为,特别是处理复杂对象结构、日期格式、字段过滤和多态类型。让我详细解释它们的协作方式和典型应用场景。

一、核心协作机制

  1. Jackson2JsonRedisSerializer
    • 负责将 Java 对象序列化为 Redis 存储的 JSON 字符串,以及将 JSON 字符串反序列化为 Java 对象。
    • 默认使用 Jackson 的默认 ObjectMapper 配置。
  2. 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 的对比

特性Jackson2JsonRedisSerializerGenericJackson2JsonRedisSerializer
类型信息 需通过 @JsonTypeInfo 显式指定 自动添加 @class 字段
目标类型 构造时必须指定(如 User.class 通用(无需指定目标类型)
多态支持 需手动配置注解 自动支持(通过类型信息)
JSON 兼容性 更简洁,适合与其他系统共享 含 Spring 特定的 @class 字段

五、总结

  • 结合使用的价值:通过自定义 ObjectMapper,可以灵活控制 Jackson2JsonRedisSerializer 的序列化和反序列化规则,满足复杂场景需求。
  • 适用场景:当你需要处理特定格式(如日期)、过滤字段、或在有限范围内支持多态时,这种组合非常有用。
  • 注意事项:Jackson2JsonRedisSerializer 仍需明确目标类型,不适合存储多种实现类的接口类型(如 List<Animal>),此时应使用 GenericJackson2JsonRedisSerializer
posted @ 2025-06-02 16:19  我爱麻辣香锅  阅读(73)  评论(0)    收藏  举报