Verwendung der Annotation Jackson @JsonProperty für Kotlin-Datenklassen
Lesezeit: 5 Minuten
Mike
kotlin 1.2.10 jackson-modul-kotlin:2.9.0
Ich habe die 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:
Wie Sie sehen können, wurden die letzten beiden Optionen falsch deserialisiert. Dieses Problem könnte gelöst werden, indem Getter @get:JsonProperty direkt eine Anmerkung hinzugefügt wird. Laut Jackson Docs sollte @JsonProperty jedoch Gettern/Settern/Feldern zugewiesen werden
Ich möchte also fragen, ob es eine zuverlässige Möglichkeit gibt, die Eigenschaft für Jackson in Kotlin zu kommentieren, um eine korrekte Serialisierung/Deserialisierung zu haben (außerdem werden alle meine Datenklassen automatisch generiert, sodass es schwierig wäre, einige zwei- oder dreizeilige Anmerkungen separat für Getter zu erstellen und Setzer)
Könnte dieses Problem andernfalls durch einige Jackson-Einstellungen behoben werden?
Gemäß den Antworten unten funktioniert Folgendes für mich
Sie brauchen nur .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY) .setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE). Das Problem hängt von der spezifischen Behandlung von “ist”-Gettern ab
– Beloo
15. Februar 2019 um 12:48 Uhr
SimY4
@JsonProperty Anmerkungen in Ihrem Code werden alle in private Felder innerhalb Ihrer Datenklasse eingefügt, und standardmäßig scannt Jackson private Felder nicht nach Anmerkungen. Sie müssen es anweisen, etwas anderes zu tun, indem Sie setzen @JsonAutoDetect Anmerkung:
@JsonAutoDetect(fieldVisibility = Visibility.ANY)
data class CurrencyInfo(
@JsonProperty("currency_info") var currencyInfo: CurrencyInfoItem?
)
Alternativ können Sie Ihre Anmerkungen zu Zugriffsmethoden verschieben:
data class CurrencyInfo(
@get:JsonProperty("currency_info") var currencyInfo: CurrencyInfoItem?
)
Danke, ich habe den Sichtbarkeitsmodifikator global eingestellt
– Mike
27. Dezember 2017 um 15:25 Uhr
Ich habe jackson-annotations-2.9.0 und es gibt keine PRIVATE Möglichkeit. Ich habe es mit versucht ANYaber die Eigenschaft wird weiterhin ignoriert. Quellcode anzeigen
– Mario Truco
28. August 2018 um 8:49 Uhr
Die Antwort unten, die verwendet @param:JsonProperty("") ist auch kritisch, wenn Sie versuchen, dies für etwas zu replizieren, das nicht passiert, wenn Sie den Wert erhalten, dh benutzerdefinierte Json-Deserialisierer, die beim Bau auftreten.
– Volleyball
11. September 2019 um 21:23 Uhr
nichts davon funktioniert bei mir
– Richa Schah
17. November 2021 um 13:44 Uhr
Hallo, in Java ist es möglich, beim Serialisieren und Deserialisieren unterschiedliche jsonproperty-Namen zu haben. Ist es möglich, ähnliches für Felder in der Kotlin-Datenklasse zu tun? Aha @get:JsonProperty aber nicht @set:Jsonproperty. stackoverflow.com/questions/8560348/…
– Erstpostkommentator
9. Juli um 21:02 Uhr
Maksim Turejew
Sie können so etwas tun:
data class CurrencyInfo @JsonCreator constructor (
@param:JsonProperty("currency_info")
@get:JsonProperty("currency_info")
val currencyInfo: CurrencyInfoItem?
)
Der obige Code wird in Java übersetzt als:
public final class CurrencyInfo {
@Nullable
private final String currencyInfo;
@JsonProperty("currency_info")
@Nullable
public final String getCurrencyInfo() {
return this.currencyInfo;
}
@JsonCreator
public CurrencyInfo(@JsonProperty("currency_info") @Nullable String currencyInfo) {
this.currencyInfo = currencyInfo;
}
}
Der Code aus der akzeptierten Antwort wird wie folgt in Java übersetzt:
Erstens (ist nicht rein unveränderlich):
@JsonAutoDetect(
fieldVisibility = Visibility.ANY
)
public final class CurrencyInfo {
@Nullable
private String currencyInfo;
@Nullable
public final String getCurrencyInfo() {
return this.currencyInfo;
}
public final void setCurrencyInfo(@Nullable String var1) {
this.currencyInfo = var1;
}
public CurrencyInfo(@JsonProperty("currency_info") @Nullable String currencyInfo) {
this.currencyInfo = currencyInfo;
}
}
Zweitens (hat wahrscheinlich Probleme mit der Deserialisierung):
public final class CurrencyInfo {
@Nullable
private final String currencyInfo;
@JsonProperty("currency_info")
@Nullable
public final String getCurrencyInfo() {
return this.currencyInfo;
}
public CurrencyInfo(@Nullable String currencyInfo) {
this.currencyInfo = currencyInfo;
}
}
val mapper = ObjectMapper().registerKotlinModule()
Dann funktioniert es (und vieles andere) automatisch.
Es wurde von Anfang an verwendet. Sie können sogar die Initialisierung im Frageposten überprüfen.
– Mike
12. Oktober 2018 um 12:39 Uhr
@ Mike ja, richtig, das habe ich verpasst. Es hat jedoch die Arbeit für mich erledigt.
– GameScripting
23. Oktober 2018 um 10:44 Uhr
Dies ist bei weitem die beste Antwort hier: Die Registrierung dieses Moduls löst nicht nur das Problem, ohne dass Sie tippen müssen @get: oder verwenden Sie andere Optimierungen, verbessert aber insgesamt die Kotlin<>Jackson-Interop.
– verrückter Kopf
19. September 2019 um 9:54 Uhr
KotlinModule() ist leider nicht in der letzten Version von Jackson enthalten, aber alle Dokumente sprechen leider über die Verwendung von KotlinModule(). niemand sagt, wie man das in der neuesten Version macht
Kotlin unterstützt die Annotationen @param und @get nicht als eine Annotation, also müssen wir diesen Code schreiben:
data class User(
@param:JsonProperty("id") @get:JsonProperty("id") val id: Int,
@param:JsonProperty("name") @get:JsonProperty("name") val name: String
)
Hier können Sie JetBrain-Mitarbeitern mitteilen, diese Funktion zu unterstützen und Folgendes zuzulassen:
data class User(
@JsonProperty("id") val id: Int,
@JsonProperty("name") val name: String
)
data class SignRequest
@param:JsonProperty("estamp_request")
@get:JsonProperty("estamp_request")
val eStamp: EstampRequest?
}
data class EstampRequest(
val tags: Map<String,Int>
)
Ivan Rodrigues
Ich bin heute auf dieses Problem gestoßen und habe KotlinModule() in meinem ObjectMapper() registriert. Faltenbälge folgen einem Beispiel.
@Bean fun objectMapper = ObjectMapper().registreModule(KotlinModule())
Darüber befindet sich ein Dummy-ObjectMapper. Ich glaube, Sie sollten andere Konfigurationen in Ihren ObjectMapper einfügen, z. B. Serializer und so weiter
10553100cookie-checkVerwendung der Annotation Jackson @JsonProperty für Kotlin-Datenklassenyes
Sie brauchen nur .setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY) .setVisibility(PropertyAccessor.IS_GETTER, JsonAutoDetect.Visibility.NONE). Das Problem hängt von der spezifischen Behandlung von “ist”-Gettern ab
– Beloo
15. Februar 2019 um 12:48 Uhr