如何在Kotlin中使用Jackson JsonSubTypes注释

时间:2014-10-28 10:07:23

标签: jackson kotlin

我正在尝试转换一些使用Jackson的@JsonSubTypes注释来管理多态的Java代码。

以下是可用的Java代码:

@JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type")
@JsonSubTypes({
    @JsonSubTypes.Type(value = Comment.class, name = "CommentNote"),
    @JsonSubTypes.Type(value = Photo.class, name = "PhotoNote"),
    @JsonSubTypes.Type(value = Document.class, name = "DocumentNote")
})
public abstract class Note implements Identifiable {
    [...]

以下是我认为相同的Kotlin代码:

JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type")
JsonSubTypes(
    JsonSubTypes.Type(value = javaClass<Comment>(), name = "CommentNote"),
    JsonSubTypes.Type(value = javaClass<Photo>(), name = "PhotoNote"),
    JsonSubTypes.Type(value = javaClass<Document>(), name = "DocumentNote")
)
abstract class Note : Identifiable {
    [...]

但是我在三个“JsonSubTypes.Type”行中都出现了以下错误:

Kotlin: An annotation parameter must be a compile-time constant
Kotlin: Annotation class cannot be instantiated

有什么想法吗?

4 个答案:

答案 0 :(得分:11)

我相信这已经解决了,现在你可以这样写:

import com.fasterxml.jackson.annotation.JsonSubTypes
import com.fasterxml.jackson.annotation.JsonTypeInfo

@JsonTypeInfo(
   use = JsonTypeInfo.Id.NAME,
   include = JsonTypeInfo.As.PROPERTY,
   property = "type")
   @JsonSubTypes(
       JsonSubTypes.Type(value = Comment::class, name = "CommentNote"),
       JsonSubTypes.Type(value = Photo::class, name = "PhotoNote"),
       JsonSubTypes.Type(value = Document::class, name = "DocumentNote"))
interface Note

请注意JsonSubTypes.Type缺少@ 课程表示法

答案 1 :(得分:8)

原来它在编译器中是bug,感谢报告它。要解决此问题,您可以导入JsonSubTypes.Type并无限制地使用它:

import org.codehaus.jackson.annotate.JsonSubTypes.Type

JsonTypeInfo(
    use = JsonTypeInfo.Id.NAME,
    include = JsonTypeInfo.As.PROPERTY,
    property = "type")
JsonSubTypes(
    Type(value = javaClass<Comment>(), name = "CommentNote"),
    Type(value = javaClass<Photo>(), name = "PhotoNote"),
    Type(value = javaClass<Document>(), name = "DocumentNote")
)
abstract class Note : Identifiable {
    [...]

答案 2 :(得分:1)

我知道这是一个古老的问题,但是,如果有人仍在寻找对杰克逊的kotlin中的继承类进行序列化/反序列化的解决方案,我建议您使用sealed类,而忽略使用{{1 }}。

我还建议使用@JsonSubTypes作为include并通过密封类内的val获取属性。否则,如果在数组中添加合并的继承对象,杰克逊将无法反序列化,并且会抛出EXISTING_PROPERTY

这是示例用法:

com.fasterxml.jackson.databind.exc.InvalidTypeIdException

这应该像一种魅力,包括在数组中使用该类!

答案 3 :(得分:0)

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXISTING_PROPERTY, property = "type")
@JsonSubTypes(
    JsonSubTypes.Type(Car::class, name = "car"),
    JsonSubTypes.Type(Truck::class, name = "truck")
)
abstract class Vehicle(val type: String)
data class Car @JsonCreator constructor(@JsonProperty("manufacturer") val manufacturer: String) : Vehicle("car")
data class Truck @JsonCreator constructor(@JsonProperty("weight") val weight: Double) : Vehicle("truck")

@Test
public fun jacksonInheritanceKt() {
    val s = "[{\"type\": \"car\", \"manufacturer\": \"audi\"}, {\"type\": \"truck\", \"weight\": 3000.0}]"

    val mapper = ObjectMapper()
    val vehicles = mapper.readValue(s, object : TypeReference<List<Vehicle>>() {})
    println(vehicles)
}