version

Rely on version
spring boot 2.5.1
jackson 2.12.3
spring-data-redis 2.5.1

To solve the problem

  1. Custom ObjectMapper Bean objects into the Spring container
  2. Common ObjectMapper serialization and deserialization configurations
  3. Added ObjectMapper support configuration for Date and LocalDateTime
  4. For RedisCache only, add NON_FINAL configuration so that RedisTemplate deserializes with the correct object type without affecting functions like @requestBody

code

Need to rely on

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-json</artifactId>
</dependency>
Copy the code

Jackson configuration

@Configuration
public class JacksonConfig {

    @Primary
    @Bean("objectMapper")
    public ObjectMapper objectMapper(a) {
        return baseObjectMapper();
    }

    @Bean(name = "redisObjectMapper")
    public ObjectMapper redisObjectMapper(a) {
        ObjectMapper objectMapper = baseObjectMapper();
        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        objectMapper.activateDefaultTyping(objectMapper.getPolymorphicTypeValidator(), ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY);
        return objectMapper;
    }

    private ObjectMapper baseObjectMapper(a) {
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
        objectMapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
        objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
        objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        objectMapper.setTimeZone(TimeZone.getTimeZone("GMT+8"));
        JavaTimeModule javaTimeModule = new JavaTimeModule();
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(dtf));
        javaTimeModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(dtf));
        objectMapper.registerModule(javaTimeModule);
        returnobjectMapper; }}Copy the code

Redis configuration

@Configuration
@EnableCaching
public class RedisConfig {
    @Bean
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory,
                                                       @Qualifier("redisObjectMapper") ObjectMapper objectMapper) {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        GenericJackson2JsonRedisSerializer jsonSerializer = new GenericJackson2JsonRedisSerializer(objectMapper);
        redisTemplate.setValueSerializer(jsonSerializer);
        redisTemplate.setHashValueSerializer(jsonSerializer);
        StringRedisSerializer stringSerializer = new StringRedisSerializer();
        redisTemplate.setKeySerializer(stringSerializer);
        redisTemplate.setHashKeySerializer(stringSerializer);
        redisTemplate.setEnableTransactionSupport(true);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }

    @Bean
    public RedisCacheManager cacheManager(RedisTemplate<Object, Object> redisTemplate) {
        returnRedisCacheManager .builder(Objects.requireNonNull(redisTemplate.getConnectionFactory())) .cacheDefaults( RedisCacheConfiguration .defaultCacheConfig() .entryTtl(Duration.ZERO) .disableCachingNullValues() .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer((StringRedisSerializer) redisTemplate.getKeySerializer())) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer())) ) .transactionAware() .build(); }}Copy the code

Pay attention to

This code defines ObjectMapper for container management, which will cause the configuration items related to Spring. Jackson to fail, and the time processing format is relatively fixed, for reference only