Регистрация ДжексонаПодтипы не работают в Котлине - PullRequest
1 голос
/ 07 марта 2019

Я пытался использовать функцию 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", поэтому десериализация не работает.

Любая идея, какисправить это?

Версия Джексона Котлина: 2.9.6

Ответы [ 2 ]

1 голос
/ 08 марта 2019

Это не связано с 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 more c3p0 gadgets to exploit default typing issue \[CVE-2018-7489\], которая была исправлена ​​в версии 2.9.5. Вы используете версию 2.9.6, и вы заметили, что поведение немного изменилось с версии 2.9.3. Что это значит для тебя? Вам нужно явно включить default typing, потому что это небезопасно. Таким образом:

MAPPER.enableDefaultTyping()

Проверьте документацию к этому методу:

ПРИМЕЧАНИЕ. Использование набора по умолчанию может представлять потенциальную угрозу безопасности, если входящий контент поступает из ненадежных источников, и рекомендуется что это либо не сделано, либо, если включено, использовать setDefaultTyping, передавая пользовательская реализация TypeResolverBuilder, которая помещает в белый список допустимые типы.

Я предлагаю прочитать Наследование с Джексоном статью и использовать последнюю версию Jackson, которая сейчас 2.9.9. Подробнее о CVE в Jackson в О CVE Джексона: не паникуйте - вот что вам нужно знать статья.

0 голосов
/ 08 марта 2019

Я понял это.

В случае, если у кого-то возникнет эта проблема в будущем, в этом конкретном примере класс Vehicle должен быть аннотирован @JsonTypeInfo следующим образом:

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