我有几个实现此TypeAlias接口的Kotlin数据类:
import com.fasterxml.jackson.annotation.JsonValue;
public interface TypeAlias<T> {
@JsonValue
T getValue();
}
以前,我一直在使用早期版本的Jackson,并且对它们进行反序列化很好。但是现在我正在使用2.9.9。
一个无法反序列化的类:
data class UserId(@NotNull private val value: EntityId) : TypeAlias<EntityId> {
@JsonCreator(mode = JsonCreator.Mode.DELEGATING)
constructor(value: String) : this(EntityId(value))
override fun getValue() = value
}
对此进行测试:
@Test
fun `Deserialization test`() {
val userIdString = "\"aaaaaaaaaaaaaaaaaaaaaa\""
mapper.readValue(userIdString, UserId::class.java)
}
此测试会爆炸:
com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Cannot construct instance of `UserId` (no Creators, like default construct, exist): no String-argument constructor/factory method to deserialize from String value ('aaaaaaaaaaaaaaaaaaaaaa')
我的映射器确实注册了KotlinModule。
请注意,UserId在其辅助String构造函数上确实有一个JsonCreator。该行为使我认为该接口导致Jackson看不到@JsonCreator批注。我在这里想念什么?
答案 0 :(得分:1)
在与几个同事一起深入研究之后,我们意识到问题与在ObjectMapper上注册模块的顺序有关。我们在Kotlin模块之后注册了一个篡改配置的模块。相反,当我们在有问题的模块之后注册Kotlin模块时,一切又恢复了。
答案 1 :(得分:0)
我在下面的代码中使用了2.9.9,并且能够反序列化。 (很抱歉将其放在答案栏中,无法在评论部分中将其正确格式化)
data class abc( private val value: def?) {
@JsonCreator(mode =JsonCreator.Mode.DELEGATING)
constructor( s: String) : this(def(s)) {
println(s)
}
}
data class def(val data: String)
fun main(args: Array<String>) {
println("Hello World!")
val m: ObjectMapper = ObjectMapper()
m.readValue("\"5abc\"", abc::class.java)
}
您可以将git链接发布到一个简单的仓库中,以便我们重现该问题吗?
答案 2 :(得分:0)
您需要一个有效的Jackson配置。看这个例子
@Configuration
class JacksonConfig {
@Bean
fun objectMapper(): ObjectMapper {
val objectMapper = ObjectMapper()
val jdk8Module = Jdk8Module().configureAbsentsAsNulls(true)
objectMapper.registerModule(jdk8Module)
objectMapper.registerModule(JavaTimeModule())
// ... your customizations
objectMapper.registerKotlinModule()
return objectMapper
}
}