You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置RedisTemplate:ObjectNode&ArrayNode用Jackson序列化器,其余用Jdk序列化器?

动态选择序列化器:针对ObjectNode/ArrayNode用Jackson,其余用JDK序列化

刚好之前碰到过类似的需求,其实可以通过自定义RedisSerializer来完美解决——核心就是在序列化/反序列化时判断目标对象的类型,动态分发到对应的序列化器处理。下面是具体的实现步骤和代码示例:

第一步:实现自定义混合序列化器

我们需要创建一个实现RedisSerializer<Object>的自定义类,内部封装两个序列化器实例:GenericJackson2JsonRedisSerializer专门处理Jackson的ObjectNode和ArrayNode类型,JdkSerializationRedisSerializer处理其他所有Java对象。

重点要注意反序列化的逻辑:因为字节数组本身不带类型信息,所以我们需要在序列化时给数据加一个类型标识位,这样反序列化时才能知道该用哪个序列化器解析。

import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.ObjectNode;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

public class HybridRedisSerializer implements RedisSerializer<Object> {

    // 初始化两个序列化器实例
    private final GenericJackson2JsonRedisSerializer jacksonSerializer = new GenericJackson2JsonRedisSerializer();
    private final JdkSerializationRedisSerializer jdkSerializer = new JdkSerializationRedisSerializer();

    @Override
    public byte[] serialize(Object obj) throws SerializationException {
        if (obj == null) {
            return new byte[0];
        }
        // 给不同类型的序列化结果添加标识位
        byte flag;
        byte[] data;
        if (obj instanceof ObjectNode || obj instanceof ArrayNode) {
            data = jacksonSerializer.serialize(obj);
            flag = 1; // 用1标记Jackson序列化的数据
        } else {
            data = jdkSerializer.serialize(obj);
            flag = 0; // 用0标记JDK序列化的数据
        }
        // 拼接标识位和实际数据
        byte[] result = new byte[data.length + 1];
        result[0] = flag;
        System.arraycopy(data, 0, result, 1, data.length);
        return result;
    }

    @Override
    public Object deserialize(byte[] bytes) throws SerializationException {
        if (bytes == null || bytes.length == 0) {
            return null;
        }
        // 先读取标识位,判断用哪个序列化器反序列化
        byte flag = bytes[0];
        byte[] data = new byte[bytes.length - 1];
        System.arraycopy(bytes, 1, data, 0, data.length);
        
        if (flag == 1) {
            return jacksonSerializer.deserialize(data);
        } else {
            return jdkSerializer.deserialize(data);
        }
    }
}

第二步:配置RedisTemplate使用自定义序列化器

在Spring的配置类中,把我们的自定义序列化器设置给RedisTemplate的value(或hashValue)序列化器即可。如果key不需要特殊处理,用StringRedisSerializer就足够了。

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;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        
        HybridRedisSerializer hybridSerializer = new HybridRedisSerializer();
        // 设置value和hashValue的序列化器为自定义混合序列化器
        template.setValueSerializer(hybridSerializer);
        template.setHashValueSerializer(hybridSerializer);
        
        // key使用字符串序列化器,避免乱码
        template.setKeySerializer(new StringRedisSerializer());
        template.setHashKeySerializer(new StringRedisSerializer());
        
        template.afterPropertiesSet();
        return template;
    }
}

一些注意事项

  • 类型标识的扩展性:上面的例子用了一个字节作为标识位,如果你以后需要支持更多序列化策略,可以扩展标识位的长度(比如用两个字节或字符串前缀)。
  • Jackson序列化的兼容性:如果你的ObjectNode/ArrayNode是通过Jackson的ObjectMapper生成的,GenericJackson2JsonRedisSerializer可以直接兼容,不需要额外配置;如果有特殊的Jackson配置,可以在初始化GenericJackson2JsonRedisSerializer时传入自定义的ObjectMapper。
  • 测试验证:一定要分别测试两种类型的序列化/反序列化:比如存入一个ObjectNode后取出,检查是否还是原类型;存入一个普通POJO(比如User类),取出后验证属性是否正确。

内容的提问来源于stack exchange,提问作者J.mos

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:49:35