Redis存储时 采用Jackson序列化的问题

Redis存储时 采用Jackson序列化的问题

当我们的项目中使用到redis时,由于redis会将数据进行序列化存储,存储的数据大多是人类无法直接阅读的,因此往往我们需要对Redis的key与value进行配置序列化器。而我通常会使用String 序列化,保证 key 可读性,Jackson 序列化value,替代默认 JDK 序列化。

@Configuration
public class RedisConfig {

    /**
     * 自定义 RedisTemplate,使用 String 序列化 key,Jackson 序列化 value
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);

        // 1. 配置 Key 的序列化器(String 序列化,保证 key 可读性)
        RedisSerializer<String> stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);

        // 2. 配置 Value 的序列化器(Jackson 序列化,替代默认 JDK 序列化)
        RedisSerializer<Object> jacksonSerializer = redisSerializer();
        redisTemplate.setValueSerializer(jacksonSerializer);
        redisTemplate.setHashValueSerializer(jacksonSerializer);


        redisTemplate.setValueSerializer(jacksonSerializer);
        redisTemplate.setHashValueSerializer(jacksonSerializer);


        // 初始化 RedisTemplate 配置
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    /**
     * 创建 Jackson 序列化器,支持 Java 8 时间类型(LocalDateTime 等)
     */
    @Bean
    public RedisSerializer<Object> redisSerializer() {
        // 初始化 ObjectMapper,解决 Java 8 时间序列化、多态类型识别问题
        ObjectMapper objectMapper = new ObjectMapper()
                // 支持多态类型(如 List<Object> 中不同子类的序列化)
                .activateDefaultTyping(LaissezFaireSubTypeValidator.instance, ObjectMapper.DefaultTyping.NON_FINAL)
                // 注册 Java 8 时间模块(解决 LocalDateTime 序列化失败问题)
                .registerModule(new JavaTimeModule());

        // 创建 Jackson 序列化器并绑定 ObjectMapper
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        serializer.setObjectMapper(objectMapper);
        return serializer;
    }
}

但我在使用该序列化器时出现了一些问题,序列化的对象为:


@Data
public class Line {
    /**
     * 时间戳 (毫秒)
     */
    private Long timestamp;
    /**
     * 开盘价
     */
    private BigDecimal open;
    /**
     * 最高价
     */
    private BigDecimal high;
    /**
     * 最低价
     */
    private BigDecimal low;
    /**
     * 收盘价
     */
    private BigDecimal close;
    /**
     * 总交易量
     */
    private BigDecimal volume;


    /**
     * 获取格式化时间字符串
     */
    public String getFormattedTime() {
        if (timestamp == null) return "";
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault())
                .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
    }
}

我在进行查询redis,然后将该对象反序列化成Line对象的时候出现了这么一个错误:

not find formattedTime field in line.java...

大致就是他存储在redis中的数据中含有formattedTime这个字段,但是我的java对象中却找不到,出现了错误。

问题出在哪了?

查阅资料发现,Jackson在进行序列化时会将类中的get方法也序列化,从而将getFormattedTime()---->formattedTime

解决:在get方法上添加注解@JsonIgnore,明确告知不要对他序列化即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值