自定義RedisTemplate,解決Redis亂碼問題

wzpro發表於2024-05-26

問題:

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

相關文章