報錯信息
Caused by: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `java.time.LocalDateTime` (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)
查看后發現是數據從redis中取出時,Jackson2反序列化數據處理LocalDateTime類型時出錯,原因是:Jackson2在序列化LocalDateTime時輸出的不是普通的字符串時間格式,而是如下所示的格式(普通時間格式:2019-02-27 12:10:17)。
"registeredTime": { "nano": 251128500, "year": 2020, "monthValue": 2, "dayOfMonth": 15, "hour": 16, "minute": 17, "second": 2, "month": "FEBRUARY", "dayOfWeek": "SATURDAY", "dayOfYear": 46, "chronology": { "@class": "java.time.chrono.IsoChronology", "id": "ISO", "calendarType": "iso8601" } }
所以是Jackson2序列化LocalDateTime跟我們所預想的不一致,將注冊給redis的序列化模板修改成以下就行。
1 import com.example.redis.pojo.User; 2 import com.fasterxml.jackson.annotation.JsonAutoDetect; 3 import com.fasterxml.jackson.annotation.JsonTypeInfo; 4 import com.fasterxml.jackson.annotation.PropertyAccessor; 5 import com.fasterxml.jackson.databind.ObjectMapper; 6 import com.fasterxml.jackson.databind.SerializationFeature; 7 import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; 8 import org.springframework.context.annotation.Bean; 9 import org.springframework.context.annotation.Configuration; 10 import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; 11 import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory; 12 import org.springframework.data.redis.core.RedisTemplate; 13 import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; 14 import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 15 import org.springframework.data.redis.serializer.StringRedisSerializer; 16 import java.io.Serializable; 17 18 @Configuration 19 public class RedisConfig { 20 21 @Bean 22 public RedisTemplate<String, Serializable> redisTemplate(LettuceConnectionFactory connectionFactory) { 23 RedisTemplate<String, Serializable> redisTemplate = new RedisTemplate<>(); 24 redisTemplate.setKeySerializer(new StringRedisSerializer()); 25 //redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer()); 26 redisTemplate.setConnectionFactory(connectionFactory); 27 //redisTemplate.setConnectionFactory(new JedisConnectionFactory()); 28 29 //下面代碼解決LocalDateTime序列化與反序列化不一致問題 30 Jackson2JsonRedisSerializer<Object> j2jrs = new Jackson2JsonRedisSerializer<>(Object.class); 31 ObjectMapper om = new ObjectMapper(); 32 om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 33 // 解決jackson2無法反序列化LocalDateTime的問題 34 om.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); 35 om.registerModule(new JavaTimeModule()); 36 om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL, JsonTypeInfo.As.PROPERTY); 37 j2jrs.setObjectMapper(om); 38 // 序列化 value 時使用此序列化方法 39 redisTemplate.setValueSerializer(j2jrs); 40 redisTemplate.setHashValueSerializer(j2jrs); 41 42 return redisTemplate; 43 } 44 45 }