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

10voto

Raman Yelianevich Points 1009

Il est possible d'avoir une paire normale de getter/setter. Il suffit de spécifier le mode d'accès dans @JsonProperty

Voici un test unitaire pour cela :

public class JsonPropertyTest {

  private static class TestJackson {

    private String color;

    @JsonProperty(value = "device_color", access = JsonProperty.Access.READ_ONLY)
    public String getColor() {
      return color;
    };

    @JsonProperty(value = "color", access = JsonProperty.Access.WRITE_ONLY)
    public void setColor(String color) {
      this.color = color;
    }

  }

  @Test
  public void shouldParseWithAccessModeSpecified() throws Exception {
    String colorJson = "{\"color\":\"red\"}";
    ObjectMapper mapper = new ObjectMapper();
    TestJackson colotObject = mapper.readValue(colorJson, TestJackson.class);

    String ser = mapper.writeValueAsString(colotObject);
    System.out.println("Serialized colotObject: " + ser);
  }
}

J'ai obtenu le résultat suivant :

Serialized colotObject: {"device_color":"red"}

7voto

Andy Talkowski Points 61

Ce n'est pas la solution que j'attendais (bien que ce soit un cas d'utilisation légitime). Mon exigence était de permettre à un client existant et bogué (une application mobile déjà publiée) d'utiliser des noms alternatifs.

La solution consiste à fournir une méthode setter séparée, comme ceci :

@JsonSetter( "r" )
public void alternateSetRed( byte red ) {
    this.red = red;
}

6voto

Arnab Das Points 63

Annoter avec @JsonAlias qui a été introduit avec Jackson 2.9+, sans mentionner @JsonProperty sur l'élément à désérialiser avec plus d'un alias (différents noms pour une propriété json) fonctionne bien.

J'ai utilisé com.fasterxml.jackson.annotation.JsonAlias pour la cohérence du paquet avec com.fasterxml.jackson.databind.ObjectMapper pour mon cas d'utilisation.

Par exemple :

@Data
@Builder
public class Chair {

    @JsonAlias({"woodenChair", "steelChair"})
    private String entityType;

}

@Test
public void test1() {

   String str1 = "{\"woodenChair\":\"chair made of wood\"}";
   System.out.println( mapper.readValue(str1, Chair.class));
   String str2 = "{\"steelChair\":\"chair made of steel\"}";
   System.out.println( mapper.readValue(str2, Chair.class));

}

fonctionne très bien.

4voto

Khaled Points 331

Je sais que c'est une vieille question, mais j'ai réussi à la faire fonctionner lorsque j'ai compris qu'il y avait un conflit avec la bibliothèque Gson, donc si vous utilisez Gson, utilisez @SerializedName("name") au lieu de @JsonProperty("name") J'espère que cela vous aidera

1voto

fetta Points 192

Ils ont dû l'inclure comme une fonctionnalité, parce que maintenant le réglage d'une différente @JsonProperty pour un getter et un setter donne exactement ce à quoi on peut s'attendre (un nom de propriété différent pendant la sérialisation et la désérialisation pour le même champ). Jackson version 2.6.7

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