怎样去掉 RedisTemplate Jackson 序列化的 class 去掉 @class

在使用 RedisTemplate 进行对象的序列化和反序列化时,如果使用的是 Jackson 库,默认情况下,会在序列化的结果中添加一个 @class 字段,用于标识对象的类型。然而,在某些场景中,我们可能不希望将对象的类型信息暴露出来,因此需要将 @class 字段去掉。本文将介绍如何去掉 RedisTemplate Jackson 序列化的 @class 字段,并提供相应的代码示例。

1. RedisTemplate 配置

首先,我们需要对 RedisTemplate 进行相应的配置。通过继承 RedisTemplate 类,并覆写 afterPropertiesSet 方法,我们可以自定义 Jackson 序列化器和反序列化器,并将其应用到 RedisTemplate 中。

public class CustomRedisTemplate extends RedisTemplate<String, Object> {

    public CustomRedisTemplate() {
        this.setDefaultSerializer(new GenericJackson2JsonRedisSerializer());
        this.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        this.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
        this.setHashKeySerializer(new StringRedisSerializer());
        this.setKeySerializer(new StringRedisSerializer());
    }

    @Override
    public void afterPropertiesSet() {
        Jackson2JsonRedisSerializer<Object> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(objectMapper);

        this.setDefaultSerializer(serializer);
        this.setValueSerializer(serializer);
        this.setHashValueSerializer(serializer);
        this.setHashKeySerializer(new StringRedisSerializer());
        this.setKeySerializer(new StringRedisSerializer());

        super.afterPropertiesSet();
    }
}

CustomRedisTemplate 中,我们使用 Jackson2JsonRedisSerializer 作为默认的序列化器和反序列化器,并配置了 ObjectMapper 对象来控制序列化的行为。通过设置 objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL),我们可以保留序列化时的类型信息。

2. 使用自定义的 RedisTemplate

接下来,我们需要在项目中使用自定义的 RedisTemplate。首先,在 Spring Boot 的配置文件中,将 RedisTemplate 的 bean 配置为我们自定义的 CustomRedisTemplate

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
        CustomRedisTemplate redisTemplate = new CustomRedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        return redisTemplate;
    }
}

然后,在需要使用 RedisTemplate 的地方,通过 @Autowired 将其注入到相应的类中。

@Service
public class RedisService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    
    // ...
}

3. 测试去掉 @class 字段

现在,我们可以进行测试,看看是否成功去掉了 Jackson 序列化中的 @class 字段。

public class RedisTest {

    @Autowired
    private RedisService redisService;

    @Test
    public void testSerialization() {
        User user = new User("John", 30);
        redisService.put("user", user);
        User cachedUser = (User) redisService.get("user");
        System.out.println(cachedUser.getName()); // Output: John
        System.out.println(cachedUser.getAge());  // Output: 30
    }
}

在这个示例中,我们将一个自定义的 User 对象存入 Redis 中,并读取出来进行验证。如果成功去掉了 @class 字段,那么输出的结果应该与原始对象保持一致。

总结

通过继承 RedisTemplate 类,并自定义 Jackson 序列化器和反序列化器,我们可以去掉 RedisTemplate Jackson 序列化的 @class 字段。这样可以在某些场景中保护对象的类型信息。但需要注意的是,去掉 @class 字段会导致反序列化时无法根据类型信息还原对象,因此在使用时需要谨慎。

旅行图

journey
    title RedisTemplate Jackson 序列化的 class 去掉 @class 旅行图

    section 配置
        配置 -> 配置RedisTemplate: 自定义RedisTemplate
        配置RedisTemplate -> 配置Spring Boot