it-swarm.com.de

Verwendung der Jackson @ JsonProperty-Annotation für Kotlin-Datenklassen

kotlin 1.2.10 jackson-module-kotlin: 2.9.0

Ich habe folgende Datenklasse in Kotlin:

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

Wenn ich versuche, diese Datenklasse zu deserialisieren, erhalte ich Folgendes:

{"currency_info":{"iso_4217":"CAD","name":"Canadian Dollar","imerchantAccount":0,"ixrateSource":2}}

Wie Sie sehen, wurden die letzten beiden Optionen falsch deserialisiert. Dieses Problem kann behoben werden, indem direkt eine Anmerkung zu getter @get: JsonProperty hinzugefügt wird. Laut jackson docs sollte @JsonProperty jedoch Gettern/Setzern/Feldern zugewiesen werden

Ich möchte also fragen, ob es eine zuverlässige Möglichkeit gibt, Eigenschaften für jackson in kotlin mit Anmerkungen zu versehen, um eine korrekte Serialisierung/Deserialisierung zu erhalten. Außerdem werden alle meine Datenklassen automatisch generiert, sodass es schwierig ist, Anmerkungen mit zwei oder drei Zeilen für Getter getrennt zu erstellen und Setter)

Andernfalls könnte dieses Problem durch einige Jackson-Einstellungen behoben werden?

Nach den unten stehenden Antworten funktioniert Folgendes für mich

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)
27
Mike

@JsonProperty Anmerkungen in Ihrem Code werden alle in privaten Feldern innerhalb Ihrer Datenklasse abgelegt, und standardmäßig durchsucht Jackson private Felder nicht nach Anmerkungen. Sie müssen es anweisen, etwas anderes zu tun, indem Sie @JsonAutoDetect Anmerkung:

@JsonAutoDetect(fieldVisibility = Visibility.ANY)
data class CurrencyInfo(
    @JsonProperty("currency_info") var currencyInfo: CurrencyInfoItem?
)

oder alternativ können Sie Ihre Anmerkungen nach Zugriffsmethoden verschieben:

data class CurrencyInfo(
    @get:JsonProperty("currency_info") var currencyInfo: CurrencyInfoItem?
)
41
SimY4

Sie können den ObjectMapper über die Jackson-Bibliothek konfigurieren, indem Sie die Methode setPropertyNamingStrategy(...) aufrufen.

Mit PropertyNamingStrategy.SNAKE_CASE sollte Ihr Problem lösen

Siehe auch die anderen verfügbaren Strategien hier: PropertyNamingStrategy

3
Prim

Sie können so etwas tun:

data class CurrencyInfo @JsonCreator constructor (
        @param:JsonProperty("currency_info") 
        @get:JsonProperty("currency_info")
        val currencyInfo: CurrencyInfoItem?
)
2
Maksim Turaev

Sie können das jackson-module-kotlin ( https://github.com/FasterXML/jackson-module-kotlin ) und registriere das kotlin Modul bei jackson:

val mapper = ObjectMapper().registerModule(KotlinModule())

Dann funktioniert es (und viele andere Dinge) automatisch.

0
GameScripting