问题:
使用默认的RedisTemplate来操作Redis,在其底层使用的是JDK序列化器,会导致数据乱码问题,可读性差,其优点是兼容性高。
解决:
自定义RedisTemplate,使用Jackson序列化器替代JDK序列化器。
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String,Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(redisSerializer);
redisTemplate.setHashKeySerializer(redisSerializer);
redisTemplate.setValueSerializer(jsonRedisSerializer());
redisTemplate.setHashKeySerializer(jsonRedisSerializer());
return redisTemplate;
}
public Jackson2JsonRedisSerializer<Object> jsonRedisSerializer() {
Jackson2JsonRedisSerializer<Object> jsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
jsonRedisSerializer.setObjectMapper(objectMapper);
return jsonRedisSerializer;
}
}
代码解释
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
setVisibility方法:用于配置ObjectMapper的可见性规则,以确定哪些属性和字段应该被序列化和反序列化。
PropertyAccessor.ALL:表示配置序列化和反序列化的可见性规则应用于所有字段(包括getter/setter,字段,creators等)。
JsonAutoDetect.Visibility.ANY:表示任何(包括private、protected和public)可见性级别的字段和方法都应该被序列化和反序列化。
作用:通过这个设置,ObjectMapper将会检测和处理所有的属性和字段,无论它们的访问级别(private、protected、public)。这对处理被声明为private但仍需要序列化/反序列化的字段非常有用。
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
configure方法:用于配置ObjectMapper的一些特定行为。
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES:这是一个DeserializationFeature选项,控制反序列化过程遇到未知属性时的行为。
false:禁用这个选项。
作用:这个配置的目的是在反序列化过程中,如果JSON数据包含在Java类中不存在的属性,ObjectMapper将不会因为这些未知属性抛出异常,而是忽略它们并继续反序列化。这确保了在处理可能包含多余或未知字段的JSON数据时的鲁棒性。
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
enableDefaultTyping方法:启用默认的类型处理机制,用于在序列化时添加类型信息并在反序列化时正确处理类型信息。
ObjectMapper.DefaultTyping.NON_FINAL:启用类型信息处理,对于所有非final类。final类如String、Integer等将不被处理。
JsonTypeInfo.As.PROPERTY:指定将类型信息作为属性包含在JSON中。
作用:启用这个配置后,ObjectMapper将会在序列化对象时添加额外的类型信息,确保反序列化时能够正确地还原对象的实际类型。将类型信息作为JSON对象的属性存储,可以在反序列化阶段使用这些信息来创建正确的对象类型。