web-dev-qa-db-fra.com

Utilisation de l'annotation Jackson @JsonProperty pour les classes de données kotlin

kotlin 1.2.10 jackson-module-kotlin: 2.9.0

J'ai la classe de données suivante dans 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?
)

Lorsque j'essaie de désérialiser cette classe de données, j'obtiens ce qui suit:

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

Comme vous pouvez le constater, les deux dernières options ont été désérialisées correctement. Ce problème pourrait être résolu en ajoutant directement une annotation à getter @get: JsonProperty. Cependant, selon Jackson docs, @JsonProperty devrait être attribué à des getters/setters/fields

Je souhaite donc savoir s’il existe un moyen fiable d’annoter la propriété de jackson dans Kotlin afin d’obtenir une sérialisation/désérialisation correcte (de plus, toutes mes classes de données sont générées automatiquement, il serait donc difficile de créer des annotations à deux/trois lignes, séparément pour getter. et passeur)

Sinon, ce problème pourrait-il être résolu par certains paramètres de Jackson?

Selon les réponses ci-dessous, ce qui suit fonctionne pour moi

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 Les annotations de votre code sont toutes placées dans des champs privés de votre classe de données et par défaut, Jackson n’analyse pas les champs privés à la recherche d’annotations. Vous devez lui demander de faire autrement en mettant @JsonAutoDetect annotation:

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

ou bien vous pouvez déplacer vos annotations sur les méthodes d'accès:

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

Vous pouvez configurer ObjectMapper à partir de la bibliothèque jackson en appelant la méthode setPropertyNamingStrategy(...)

En utilisant PropertyNamingStrategy.SNAKE_CASE devrait résoudre votre problème

Voir aussi les autres stratégies disponibles ici: PropertyNamingStrategy

3
Prim

Vous pouvez faire quelque chose comme ça:

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

Vous pouvez ajouter le jackson-module-kotlin ( https://github.com/FasterXML/jackson-module-kotlin ) et enregistrez le module kotlin auprès de jackson:

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

Ensuite, cela (et bien d’autres choses) fonctionne automatiquement.

0
GameScripting