Jackson registerSubtypes not working in Kotlin

橙三吉。 提交于 2019-12-11 07:55:01

问题


I was trying to use the registerSubtypes function from Jackson following this tutorial.

So I've converted this code into Kotlin like so:

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)
}

But the output result is the following:

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

It doesn't contain the "@type" field, so deserialization doesn't work.

Any idea how to fix it?

Jackson Kotlin version: 2.9.6


回答1:


It is not related with Kotlin. Linked article uses Jackson in version 2.9.3. But a little bit later Another two gadgets to exploit default typing issue in jackson-databind (CVE-2018-5968) bug appeared and Jackson had to fixed that. In Jackson Release 2.9.4 this bug was fixed. Later on, new bug was created: Two morec3p0gadgets to exploit default typing issue \[CVE-2018-7489\] which was fixed in version 2.9.5. You are using version 2.9.6 and you noticed that behaviour changed a little bit since version 2.9.3. What does it mean for you? You need to enable default typing explicitly because it is not secure. This way:

MAPPER.enableDefaultTyping()

Check documentation to this method:

NOTE: use of Default Typing can be a potential security risk if incoming content comes from untrusted sources, and it is recommended that this is either not done, or, if enabled, use setDefaultTyping passing a custom TypeResolverBuilder implementation that white-lists legal types to use.

I suggest to read Inheritance with Jackson article and use the latest version of Jackson which right now is 2.9.9. Read more about CVE in Jackson in On Jackson CVEs: Don’t Panic — Here is what you need to know article.




回答2:


I've figured it out.

In case anyone has this issue in the future, in this particular example the Vehicle class would need to be annotated with @JsonTypeInfo like so :

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


来源:https://stackoverflow.com/questions/55049171/jackson-registersubtypes-not-working-in-kotlin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!