杰克逊寄存器子类型在科特林不起作用

时间:2019-03-07 16:59:00

标签: json kotlin jackson jackson2

我试图在this tutorial之后使用registerSubtypes中的Jackson函数。

因此,我已将这段代码转换为Kotlin,如下所示:

interface Vehicle {
    val name: String
}
class Car @JsonCreator constructor(@JsonProperty("name") override val name: String) : Vehicle
class Truck @JsonCreator constructor(@JsonProperty("name") override val name: String) : Vehicle

class Vehicles @JsonCreator constructor(@JsonProperty("vehicles") var vehicles: List<Vehicle>)

fun main() {
    val MAPPER = jacksonObjectMapper()
    MAPPER.registerSubtypes(NamedType(Truck::class.java, "Truck"))
    MAPPER.registerSubtypes(NamedType(Car::class.java, "Car"))

    val vehicles = Vehicles(listOf(Car("Dodge"), Truck("Scania")))
    val json = MAPPER.writerWithDefaultPrettyPrinter().writeValueAsString(vehicles)
    println(json)
}

但是输出结果如下:

{
  "vehicles" : [ {
    "name" : "Dodge"
  }, {
    "name" : "Scania"
  } ]
}

它不包含"@type"字段,因此反序列化不起作用。

有什么想法要解决吗?

Jackson Kotlin版本:2.9.6

2 个答案:

答案 0 :(得分:1)

它与Kotlin无关。链接的文章使用Jackson版的2.9.3。但是过了一会儿,Another two gadgets to exploit default typing issue in jackson-databind (CVE-2018-5968)错误出现了,Jackson不得不解决了。在Jackson Release 2.9.4中,此错误已修复。后来,创建了新的错误:Two morec3p0gadgets to exploit default typing issue \[CVE-2018-7489\],该错误已在版本2.9.5中修复。您正在使用2.9.6版,并且注意到自2.9.3版以来,行为有所改变。这对您意味着什么?您需要显式启用default typing,因为它不安全。这样:

MAPPER.enableDefaultTyping()

检查此方法的文档:

  

注意:如果出现以下情况,使用默认键入可能会带来安全隐患   传入内容来自不受信任的来源,因此建议   要么没有完成,要么(如果启用)使用setDefaultTyping传递一个   自定义TypeResolverBuilder实现,该实现将要使用的合法类型列入白名单。

我建议阅读Inheritance with Jackson文章,并使用2.9.9的最新版本Jackson。在CVE文章的Jackson中详细了解On Jackson CVEs: Don’t Panic — Here is what you need to know

答案 1 :(得分:0)

我知道了。

万一将来有人遇到此问题,在此特定示例中,Vehicle类将需要使用@JsonTypeInfo进行注释,如下所示:

@JsonTypeInfo(use = NAME, include = PROPERTY)
interface Vehicle