Использование аннотации Jackson @JsonProperty для классов данных kotlin
kotlin 1.2.10 jackson-module-kotlin: 2.9.0
У меня есть следующий класс данных в котлине:
data class CurrencyInfo(
@JsonProperty("currency_info") var currencyInfo: CurrencyInfoItem?
)
@JsonInclude(JsonInclude.Include.NON_NULL)
data class CurrencyInfoItem(
@JsonProperty("iso_4217") var iso4217: String?,
@JsonProperty("name") var name: String?,
@JsonProperty("name_major") var nameMajor: String?,
@JsonProperty("name_minor") var nameMinor: String?,
@JsonProperty("i_ma_currency") var iMaCurrency: Int?,
@JsonProperty("i_merchant_account") var iMerchantAccount: Int?,
@JsonProperty("i_x_rate_source") var iXRateSource: Int?,
@JsonProperty("base_units") var baseUnits: Double?,
@JsonProperty("min_allowed_payment") var minAllowedPayment: Int?,
@JsonProperty("decimal_digits") var decimalDigits: Int?,
@JsonProperty("is_used") var isUsed: Boolean?
)
Когда я пытаюсь десериализовать этот класс данных, я получаю следующее:
{"currency_info":{"iso_4217":"CAD","name":"Canadian Dollar","imerchantAccount":0,"ixrateSource":2}}
Как вы можете видеть, последние два параметра были десериализованы неправильно. Эта проблема может быть решена путем добавления аннотации к getter @get: JsonProperty. Однако, согласно джексону, docs @JsonProperty следует назначить для getters/setters/fields
Итак, я хочу спросить, есть ли надежный способ аннотировать свойство для jackson в kotlin, чтобы иметь правильную сериализацию/десериализацию (более того, все мои классы данных автогенерируются, поэтому было бы сложно создать несколько аннотаций из двух/трех строк, отдельно для getter и сеттер)
В противном случае, можно ли решить эту проблему с помощью некоторых настроек джексона?
Согласно нижеприведенным ответам, для меня работают следующие работы
private val mapper = ObjectMapper().registerKotlinModule()
.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY)
.setVisibility(PropertyAccessor.CREATOR, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.GETTER, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.SETTER, JsonAutoDetect.Visibility.NONE)
.setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE)
Ответы
Ответ 1
@JsonProperty
аннотации @JsonProperty
в вашем коде размещаются в приватных полях вашего класса данных. И по умолчанию Джексон не сканирует приватные поля для аннотаций. Вы должны JsonAutoDetect
это сделать иначе, JsonAutoDetect
аннотацию JsonAutoDetect
:
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
data class CurrencyInfo(
@JsonProperty("currency_info") var currencyInfo: CurrencyInfoItem?
)
или же вы можете переместить свои аннотации на методы доступа:
data class CurrencyInfo(
@get:JsonProperty("currency_info") var currencyInfo: CurrencyInfoItem?
)
Ответ 2
Вы можете настроить ObjectMapper из библиотеки jackson, вызвав метод setPropertyNamingStrategy(...)
Использование PropertyNamingStrategy.SNAKE_CASE
должно решить вашу проблему
См. Также другие доступные стратегии здесь: PropertyNamingStrategy
Ответ 3
Вы можете добавить jackson-module-kotlin
(https://github.com/FasterXML/jackson-module-kotlin) и зарегистрировать модуль kotlin с помощью jackson:
val mapper = ObjectMapper().registerModule(KotlinModule())
Затем он (и многое другое) работает автоматически.