使用泛型子类的Jackson / Spring反序列化

时间:2018-04-08 18:16:11

标签: java spring jackson kotlin json-deserialization

首先我正在使用kotlin和spring。

我想要做的是有一个过滤器基类/抽象类/接口,基本上没什么。它应该有两个孩子,每个孩子都有自己的属性。让我展示一些代码:

 abstract class AxisFilter<T : Comparable<T>>()

data class SingleAxisFilter<T : Comparable<T>>(
        val value: T,
        val isAbove: Boolean?,
        val isMatch: Boolean
) : AxisFilter<T>()

data class DualAxisFilter<T : Comparable<T>>(
        val lowerBound: T,
        val upperBound: T,
        val isBetween: Boolean,
        val inclusive: Boolean = true
) : AxisFilter<T>()

我写了一个serilalizer:

class AxisFilterDeserializer<T : Comparable<T>> : JsonDeserializer<AxisFilter<T>>() {
  override fun deserialize(jsonParser: JsonParser, deserializationContext: DeserializationContext): AxisFilter<T> {
    val oc: ObjectCodec = jsonParser.getCodec()
    val node: JsonNode = oc.readTree(jsonParser)

    return if(node.has("lowerBound"))
      DualAxisFilter<T>(
              lowerBound = node.get("lowerBound") as T,
              upperBound = node.get("upperBound") as T,
              isBetween = node.get("isBetween") as Boolean,
              inclusive = if(node.has("inclusive")) node.get("inclusive") as Boolean else true)
    else
        SingleAxisFilter<T>(
                value = node.get("value") as T,
                isAbove = if(node.has("isAbove")) node.get("isAbove") as Boolean else null,
                isMatch = node.get("isMatch") as Boolean
        )
  }
}

并尝试使用@JsonDeserialize注释,但它不起作用 - 或者我似乎无法使其工作。

@Type(value = SingleAxisFilter)@Type(value = DualAxisFilter)也因为泛型而失败。

希望有人可以帮我解决这个问题。

1 个答案:

答案 0 :(得分:0)

原则上你要做的就是:

@JsonTypeInfo(use=JsonTypeInfo.Id.CLASS, include=JsonTypeInfo.As.PROPERTY, property="@class")
    abstract class AxisFilter<T : Comparable<T>>()

    class SingleAxisFilter<T : Comparable<T>>(
            val value: T,
            val isAbove: Boolean?,
            val isMatch: Boolean
    ) : AxisFilter<T>()

    class DualAxisFilter<T : Comparable<T>>(
            val lowerBound: T,
            val upperBound: T,
            val isBetween: Boolean,
            val inclusive: Boolean = true
    ) : AxisFilter<T>()

然后在JSON请求对象中,您必须提供带有完整路径的@class属性:

{
    "value": 5.0,
    "isMatch": true,
    "isAbove": null,
    "@class": "com.blbla.common.SingleAxisFilter"
}