spring-boot - 在 Kotlin 中使用 Jackson2JsonRedisSerializer 的通用 RedisTemplate

标签 spring-boot kotlin redis jackson spring-data-redis

我的 Controller 使用 Redis 模板从 Redis 获取和设置数据

val redisTemplate: RedisTemplate<String, Game>

模板是使用 bean 注入(inject)的

@Bean
fun <T> redisTemplate(builder: RestTemplateBuilder): RedisTemplate<String, T> {
    val serializer = Jackson2JsonRedisSerializer(Game::class.java)
    serializer.setObjectMapper(objectMapper)

    val template = RedisTemplate<String, T>()
    template.setConnectionFactory(connectionFactory())
    template.setDefaultSerializer(serializer)
    return template
}

这有效,但是我必须明确要序列化的顶级类,因此返回的模板仅适用于 RedisTemplate<String, Game>而不是RedisTemplate<String, T> .

我尝试将序列化器实例化更改为以下内容,但它无法编译。

val serializer = Jackson2JsonRedisSerializer(T::class.java)

我尝试将其更改为以下内容

val serializer = Jackson2JsonRedisSerializer(Object::class.java)

可以编译,但从 redis 读取时出现异常

java.lang.ClassCastException: class java.util.LinkedHashMap cannot be cast to class com.noicesoftware.redis.model.Game (java.util.LinkedHashMap is in module java.base of loader 'bootstrap'; com.noicesoftware.redis.model.Game is in unnamed module of loader 'app')

我尝试使用 GenericJackson2JsonRedisSerializer,但我得到了上述行为和异常。

val serializer = GenericJackson2JsonRedisSerializer(objectMapper)

任何想法将不胜感激。完整的代码可以在这里找到; https://github.com/DangerousDarlow/springboot-redis

最佳答案

我一直无法找到保持 bean 通用的解决方案。如果我使类型具体化,那么我还必须使函数内联,然后是私有(private)的或最终的。这会导致运行时错误。我的解决方案是将通用代码移至私有(private)内联函数中,然后为我想要的每个模板类型声明一个 bean。虽然没有我希望的那么整洁,但我想也不算太糟糕。

private inline fun <reified T> getRedisTemplate(): RedisTemplate<String, T> {
    val serializer = Jackson2JsonRedisSerializer(T::class.java)
    serializer.setObjectMapper(objectMapper)

    val template = RedisTemplate<String, T>()
    template.setConnectionFactory(connectionFactory())
    template.setDefaultSerializer(serializer)
    return template
}

@Bean
fun redisTemplate(): RedisTemplate<String, Game> = getRedisTemplate()

关于spring-boot - 在 Kotlin 中使用 Jackson2JsonRedisSerializer 的通用 RedisTemplate,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59688967/

相关文章:

java - 如何在spring boot中注册jpa转换器?

java - Spring Boot + JPA+Thymeleaf+Hibernate 应用多重验证注解

java - MockMvc 后期测试失败

android-studio - Jetpack Compose 方法实现未显示(Ctrl 在悬停时不突出显示功能)

java - 我应该关注哪里来支持所有 100% 的手机和平板电脑,而忽略它们的屏幕尺寸或密度?

mysql - 无需轮询即可订阅 MySQL 数据库中的更改

redis - Redis MATCH操作中如何使用OR条件

php - phpredis pipeline和使用协议(protocol)批量插入一样吗?

Java 异常和 HTTP 500 错误

java - 如何解决 native Java 或 Kotlin 中的错误 "The minCompileSdk (31) specified in a dependency' s AAR metadata”?