問題:
使用預設的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物件的屬性儲存,可以在反序列化階段使用這些資訊來建立正確的物件型別。