207 votes

Noms différents de la propriété JSON pendant la sérialisation et la désérialisation

Est-il possible d'avoir un seul champ dans une classe, mais des noms différents pour celui-ci lors de la sérialisation/désérialisation dans la bibliothèque Jackson ?

Par exemple, j'ai la classe "Coordiantes".

class Coordinates{
  int red;
}

Pour la désérialisation à partir de JSON, je veux avoir un format comme celui-ci :

{
  "red":12
}

Mais quand je vais sérialiser l'objet, le résultat devrait être comme celui-ci :

{
  "r":12
}

J'ai essayé de mettre cela en œuvre en appliquant @JsonProperty à la fois sur le getter et le setter (avec des valeurs différentes) :

class Coordiantes{
    int red;

    @JsonProperty("r")
    public byte getRed() {
      return red;
    }

    @JsonProperty("red")
    public void setRed(byte red) {
      this.red = red;
    }
}

mais j'ai eu une exception :

org.codehaus.jackson.map.exc.UnrecognizedPropertyException : Champ "rouge" non reconnu

252voto

Max Points 9361

Je viens de tester et cela fonctionne :

public class Coordinates {
    byte red;

    @JsonProperty("r")
    public byte getR() {
      return red;
    }

    @JsonProperty("red")
    public void setRed(byte red) {
      this.red = red;
    }
}

L'idée est que les noms des méthodes doivent être différents, afin que Jackson les analyse comme des champs différents, et non comme un seul champ.

Voici le code de test :

Coordinates c = new Coordinates();
c.setRed((byte) 5);

ObjectMapper mapper = new ObjectMapper();
System.out.println("Serialization: " + mapper.writeValueAsString(c));

Coordinates r = mapper.readValue("{\"red\":25}",Coordinates.class);
System.out.println("Deserialization: " + r.getR());

Résultat :

Serialization: {"r":5}
Deserialization: 25

0 votes

Est-ce que la même chose est possible avec jaxb ?

0 votes

Cela fonctionnera-t-il pour Enum s ?

82voto

Asura Points 539

Vous pouvez utiliser @jsonAlias qui a été introduit dans jackson 2.9.0

Exemple :

public class Info {
  @JsonAlias({ "red" })
  public String r;
}

Cela utilise r pendant la sérialisation, mais permet red comme un alias pendant la désérialisation. Cela permet toujours r doit être désérialisée aussi, cependant.

28voto

Xaero Degreaz Points 626

Vous pouvez utiliser une combinaison de @JsonSetter y @JsonGetter pour contrôler la désérialisation et la sérialisation de votre propriété, respectivement. Cela vous permettra également de conserver des noms de méthodes getter et setter standardisés qui correspondent au nom réel de votre champ.

import com.fasterxml.jackson.annotation.JsonSetter;    
import com.fasterxml.jackson.annotation.JsonGetter;

class Coordinates {
    private int red;

    //# Used during serialization
    @JsonGetter("r")
    public int getRed() {
        return red;
    }

    //# Used during deserialization
    @JsonSetter("red")
    public void setRed(int red) {
        this.red = red;
    }
}

17voto

DRCB Points 1229

Je lierais deux paires getters/setters différentes à une variable :

class Coordinates{
    int red;

    @JsonProperty("red")
    public byte getRed() {
      return red;
    }

    public void setRed(byte red) {
      this.red = red;
    }

    @JsonProperty("r")
    public byte getR() {
      return red;
    }

    public void setR(byte red) {
      this.red = red;
    }
}

16 votes

Mais dans ce cas, lors de la sérialisation, nous obtiendrons les deux propriétés : "r" et "red", avec les mêmes valeurs.

0 votes

@JsonIgnore sur les méthodes que vous ne voulez pas traiter résoudra ce problème.

0 votes

Il existe aujourd'hui des annotations plus pratiques : @JsonGetter y @JsonSetter . On peut donc définir exactement comment le sérialiseur se comportera.

11voto

Vous pouvez utiliser cette variante :

import lombok.Getter;
import com.fasterxml.jackson.annotation.JsonGetter;
import com.fasterxml.jackson.annotation.JsonProperty;

//...

@JsonProperty(value = "rr") // for deserialization
@Getter(onMethod_ = {@JsonGetter(value = "r")}) // for serialization
private String rrrr;

avec Lombok getter

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X