使用GenericJackson2JsonRedisSerializer
GenericJackson2JsonRedisSerializer是spring提供的一个类,直接配一下
@Bean
fun redisTemplate(redisConnectionFactory: LettuceConnectionFactory): RedisTemplate<String, Any> {
val template = RedisTemplate<String, Any>()
val genericJackson2JsonRedisSerializer = GenericJackson2JsonRedisSerializer()
template.keySerializer = StringRedisSerializer()
template.valueSerializer = genericJackson2JsonRedisSerializer
template.setConnectionFactory(redisConnectionFactory)
return template
}
先写入redis,发现写入没有问题
@Autowired
private lateinit var redisTemplate: RedisTemplate<String, Any>
//写入的value为"aa"
redisTemplate.opsForValue().set("aaa","aa",100,TimeUnit.SECONDS)
val p = Passenger(1,"zhangsan", LocalDateTime.parse("2018-08-09T12:33:22.123"))
val ps = listOf(Passenger(1,"zhangsan", LocalDateTime.parse("2018-08-09T12:33:22.123")))
//写入的value为{"id":1,"name":"zhangsan","birthday":{"month":"AUGUST","year":2018,"hour":12,"minute":33,"nano":123000000,"second":22,"dayOfMonth":9,"dayOfWeek":"THURSDAY","dayOfYear":221,"monthValue":8,"chronology":{"@class":"java.time.chrono.IsoChronology","id":"ISO","calendarType":"iso8601"}},"books":["java.util.Collections$SingletonList",[{"id":1,"name":"ss","produceTime":{"month":"AUGUST","year":2018,"hour":12,"minute":33,"nano":123000000,"second":22,"dayOfMonth":9,"dayOfWeek":"THURSDAY","dayOfYear":221,"monthValue":8,"chronology":{"@class":"java.time.chrono.IsoChronology","id":"ISO","calendarType":"iso8601"}}}]]}
redisTemplate.opsForValue().set("users",ps,100,TimeUnit.SECONDS)
//写入的value为["java.util.Collections$SingletonList",[{"@class":"com.example.demo1.Passenger","id":1,"name":"zhangsan","birthday":{"month":"AUGUST","year":2018,"hour":12,"minute":33,"nano":123000000,"second":22,"dayOfMonth":9,"dayOfWeek":"THURSDAY","dayOfYear":221,"monthValue":8,"chronology":{"@class":"java.time.chrono.IsoChronology","id":"ISO","calendarType":"iso8601"}},"books":null}]]
redisTemplate.opsForValue().set("user",p,100,TimeUnit.SECONDS)
可以看到spring是把class的具体类型序列化进去了,这种方法是非常不推荐的,在多语言共同读取redis的时候会出现问题,暂且不探讨这个,读取下试试,出现了异常
val aaa = redisTemplate.opsForValue().get("aaa")
val aaaget = redisTemplate.opsForValue().get<String>("aaa")
println("aaa=$aaa")
println("aaaget=$aaaget")
//此处报错
val passenger = redisTemplate.opsForValue().get("user")
if(passenger != null){
val passengerX = mapper.convertValue<Passenger>(passenger)
println("passengerX=$passengerX")
}
val passengers = redisTemplate.opsForValue().get("users")
if(passengers != null){
val passengersX = mapper.convertValue<List<Passenger>>(passengers)
println("passengersX:$passengersX")
}
报如下异常
falseCould not read JSON: Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property '@class' at [Source: (byte[])"{"id":1,"name":"zhangsan","birthday":{"month":"AUGUST","year":2018,"hour":12,"minute":33,"nano":123000000,"second":22,"dayOfMonth":9,"dayOfWeek":"THURSDAY","dayOfYear":221,"monthValue":8,"chronology":{"@class":"java.time.chrono.IsoChronology","id":"ISO","calendarType":"iso8601"}},"books":["java.util.Collections$SingletonList",[{"id":1,"name":"ss","produceTime":{"month":"AUGUST","year":2018,"hour":12,"minute":33,"nano":123000000,"second":22,"dayOfMonth":9,"dayOfWeek":"THURSDAY","dayOfYear":221,"m"[truncated 110 bytes]; line: 1, column: 610]; nested exception is com.fasterxml.jackson.databind.exc.InvalidTypeIdException: Missing type id when trying to resolve subtype of [simple type, class java.lang.Object]: missing type id property '@class' at [Source: (byte[])"{"id":1,"name":"zhangsan","birthday":{"month":"AUGUST","year":2018,"hour":12,"minute":33,"nano":123000000,"second":22,"dayOfMonth":9,"dayOfWeek":"THURSDAY","dayOfYear":221,"monthValue":8,"chronology":{"@class":"java.time.chrono.IsoChronology","id":"ISO","calendarType":"iso8601"}},"books":["java.util.Collections$SingletonList",[{"id":1,"name":"ss","produceTime":{"month":"AUGUST","year":2018,"hour":12,"minute":33,"nano":123000000,"second":22,"dayOfMonth":9,"dayOfWeek":"THURSDAY","dayOfYear":221,"m"[truncated 110 bytes]; line: 1, column: 610]
我猜测这可能是spring data redis的一个bug,估计会在后续版本修复,事实上可以通过重设ObjectMapper来自定义序列化,不过这样就改变spring实现这个类的初衷了
val genericJackson2JsonRedisSerializer = GenericJackson2JsonRedisSerializer(ObjectMapperExtension.instance)