kotlin使用spring data redis(二)

原创
2018/09/28 11:13
阅读数 1K

自定义序列化器

1.标准json序列化器,时间类型禁用时间戳

import com.fasterxml.jackson.core.JsonProcessingException
import com.fasterxml.jackson.databind.ObjectMapper
import com.fasterxml.jackson.databind.SerializationFeature
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
import com.fasterxml.jackson.module.kotlin.readValue
import org.springframework.data.redis.serializer.RedisSerializer
import org.springframework.data.redis.serializer.SerializationException

open class Jackson2Serializer : RedisSerializer<Any> {
    private var mapper: ObjectMapper = jacksonObjectMapper()

    init {
        mapper.registerModules(Jdk8Module(), JavaTimeModule())
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
    }

    override fun serialize(t: Any?): ByteArray? {
        if (t == null) {
            return ByteArray(0)
        }

        try {
            return mapper.writeValueAsBytes(t)
        } catch (e: JsonProcessingException) {
            throw SerializationException("Could not write JSON: " + e.message, e)
        }


    }

    override fun deserialize(bytes: ByteArray?): Any? {
        if (bytes == null) {
            return null
        }

        try {
            return mapper.readValue(bytes)
        } catch (e: Exception) {
            throw SerializationException("Could not read JSON: " + e.message, e)
        }
    }

}

2.支持压缩(zstd)

import com.fasterxml.jackson.core.JsonProcessingException
import com.github.luben.zstd.Zstd
import org.springframework.data.redis.serializer.SerializationException
import java.lang.Exception

class Jackson2ZstdSerializer : Jackson2Serializer() {


    override fun serialize(t: Any?): ByteArray? {

        if (t == null) {
            return ByteArray(0)
        }
        try {
            val json = super.serialize(t)
            val compressContent = Zstd.compress(json)
            val compressHeader = "zstd_${json!!.size}_".toByteArray()
            return compressHeader + compressContent
        } catch (e: JsonProcessingException) {
            throw e
        } catch (ex: Exception) {
            throw SerializationException("Could not compress JSON: " + ex.message, ex)
        }
    }

    override fun deserialize(bytes: ByteArray?): Any? {
        if (bytes == null) {
            return null
        }

        try {
            var counter = 0
            bytes.forEachIndexed { index, byte ->
                run {
                    if (byte == '_'.toByte()) {
                        counter++
                        if(counter == 2){
                            counter = index
                            return@forEachIndexed
                        }
                    }
                }
            }


            val compressHeader = bytes.sliceArray(0..counter)
            val compressHeaderString = String(compressHeader)
            if (!compressHeaderString.contains("zstd")) {
                return null
            }
            val originContentLength = "[0-9]+".toRegex().find(compressHeaderString)?.value ?: return null
            val compressContent = bytes.sliceArray((counter + 1)..(bytes.size - 1))
            val decompressLength = if (compressContent.size > originContentLength.length) compressContent.size else originContentLength.length
            val decompressContent = Zstd.decompress(compressContent, decompressLength)
            return super.deserialize(decompressContent)

        } catch (e: Exception) {
            throw SerializationException("Could not read JSON: " + e.message, e)
        }
    }

3.启用Jackson2ZstdSerializer

@Configuration
class RedisCacheAutoConfiguration {

    @Bean
    fun redisTemplate(redisConnectionFactory: LettuceConnectionFactory): RedisTemplate<String, Any> {

        val template = RedisTemplate<String, Any>()
        template.keySerializer = StringRedisSerializer()
        template.valueSerializer = Jackson2ZstdSerializer()
        template.setConnectionFactory(redisConnectionFactory)
        return template
    }
}

4.用起来吧

@Autowired
  private lateinit var redisTemplate: RedisTemplate<String, Any>
  
    redisTemplate.opsForValue().set("aaa","aa",100,TimeUnit.SECONDS)
        val p = Passenger(1,"zhangsan", LocalDateTime.parse("2018-08-09T12:33:22.123"))
        redisTemplate.opsForValue().set("user",p,100,TimeUnit.SECONDS)

5.用Redis Desk Manager看一下

展开阅读全文
打赏
0
1 收藏
分享
加载中
更多评论
打赏
0 评论
1 收藏
0
分享
OSCHINA
登录后可查看更多优质内容
返回顶部
顶部