问题
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