web-dev-qa-db-fra.com

Jackson ne remplace pas Getter avec @JsonProperty

JsonProperty ne remplace pas le nom par défaut que jackson obtient du getter. Si je sérialise la classe ci-dessous avec ObjectMapper et jackson, je reçois

{"hi":"hello"}

Comme vous pouvez le constater, l'annotation JsonProperty n'a aucun effet

class JacksonTester {
    String hi;

    @JsonProperty("hello")
    public String getHi() {
        return hi;
    }
}   

Mettre @JsonProperty sur la chaîne elle-même ne fonctionne pas non plus. Il me semble que le seul moyen de changer le nom consiste à renommer le getter. Le seul problème est qu’il sera toujours en minuscule pour la première lettre.

10
tt_Gantz

Le problème était que j'utilisais les anciennes et les nouvelles bibliothèques jackson

c’est-à-dire que j’avais auparavant import org.codehaus.jackson.annotate.JsonProperty; Ce que j’ai du changer, pour être cohérent avec la bibliothèque que j’utilisais. 

Depuis que j'utilisais maven, cela impliquait également de mettre à jour mes dépendances maven .import com.fasterxml.jackson.annotation.JsonProperty;

Pour que cela fonctionne, j'avais besoin de l'annotation @JsonProperty sur le getter (le placer sur l'objet ne fonctionnait pas)

J'ai trouvé la réponse ici (merci à francescoforesti) @JsonProperty ne fonctionne pas comme prévu

19
tt_Gantz

J'ai eu ce problème lors de la mise à jour de l'ancienne version à la 2.8.3 de FasterXML Jackson. 

Le problème était lors de la désérialisation de la réponse JSON de notre base de données en objet de classe Java. Notre code n'avait pas @JsonSetter sur les paramètres de la classe. Par conséquent, lors de la sérialisation, la sortie n'utilisait pas les getters de la classe pour sérialiser l'objet de classe Java en JSON (le décorateur @JsonProperty() ne prenait donc pas effet). 

J'ai résolu le problème en ajoutant @JsonSetter("name-from-db") à la méthode setter pour cette propriété. 

En outre, au lieu de @JsonProperty(), pour renommer des propriétés à l'aide de la méthode getter, vous pouvez et devez utiliser @JsonGetter(), qui est plus spécifique à l'attribution d'un nouveau nom aux propriétés. 

Voici notre code:

public class KwdGroup {
    private String kwdGroupType;

    // Return "type" instead of "kwd-group-type" in REST API response
    @JsonGetter("type") // Can use @JsonProperty("type") as well
    public String getKwdGroupType() {
        return kwdTypeMap.get(kwdGroupType);
    }

    @JsonSetter("kwd-group-type") // "kwd-group-type" is what JSON from the DB API outputs for code to consume 
    public void setKwdGroupType(String kwdGroupType) {
        this.kwdGroupType = kwdGroupType;
    }
}
3
Xchai

J'ai eu même proplem

Vous devez simplement remplacer import Import com.fasterxml.jackson.annotation.JsonProperty; On Import org.codehaus.jackson.annotate.JsonProperty; Son travail.

1
Dmitriy S

Les cas de chameaux semblent toujours avoir des problèmes, même après avoir défini les annotations appropriées .. Exemple:

@JsonProperty ("mirrorport") private String mirrorPort;

La désérialisation échoue quand xml a <mirrorport>YES</mirrorport>

1
gpushkas

Avez-vous essayé ci-dessous 

class JacksonTester {
    private String hi;

    @JsonProperty("hello")
    public String getHi() {
        return hi;
    }
}   

Je veux dire faire de la déclaration de variable 'hi' en tant que private . Sinon, essayez de mettre @JsonIgnore sur la déclaration de variable et au cas où vous préféreriez le conserver à la portée par défaut.

0
vvs

Il me manquait la dépendance de databind 

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>${fasterxml.version}</version>
</dependency>
0
Ketan Keshri

Je suis récemment tombé sur une autre tournure intéressante sur cette question. Nous avons commencé à utiliser Hibernate5Module pour résoudre certains problèmes de chargement paresseux. De plus, nous utilisons Groovy, nous ne définissons donc pas les getters et les setters.

Il s'avère que le module Hibernate semble interférer avec l'annotation @JsonProperty. Plus précisément si vous avez annoté quelque chose avec @Transient Donc, si vous avez quelque chose comme:

@Transient
@ApiModelProperty(required = true)
@JsonProperty("alternateName")
String property

Vous ne verrez pas la alternateName dans le JSON. De plus, vos clients auront probablement des problèmes avec leurs POST et PUT! Pour résoudre ce problème, vous pouvez utiliser une solution de contournement simple. Définissez les getters et les setters pour le nom interne que vous devez utiliser (*) et n'utilisez pas l'attribut value sur @JsonProperty Cela fonctionne donc:

@Transient
@ApiModelProperty(required = true)
@JsonProperty
String alternateName

void setProperty(String property) {
    this.alternateName = property
}

@JsonIgnore
String getProperty() {
    this.alternateName
}

Notez l'utilisation du @JsonIgnore sur le getter. Si vous ne le faites pas, votre infrastructure le prendra probablement et vous aurez des entrées en double pour la même chose dans votre JSON.

Quoi qu'il en soit, j'espère que cela aidera quelqu'un!

(*) Nous essayions d'adhérer à une interface particulière, en appliquant ainsi le nom en interne. Cependant, l'API exposée avait besoin d'un nom différent et convivial.

0
Michael Kolakowski

Placez-le sur la variable, pas le getter

class JacksonTester {
    @JsonProperty("hello")
    private String hi;

    public String getHi() {
        return hi;
    }
} 
0
mprivat