web-dev-qa-db-fra.com

Annotations Jackson: différence entre JsonIgnoreProperties (ignoreUnknown = true) et JsonInclude (Include.NON_EMPTY)

Je suis curieux, y a-t-il une différence entre les annotations Jackson @JsonIgnoreProperties (ignoreUnknown = true) et @JsonInclude (Include.NON_EMPTY) au niveau de la classe? L'un est-il simplement une version plus récente de l'autre? Merci!

Les jackson docs indiquent que:

ignoreUnknown Propriété qui définit s'il est correct d'ignorer simplement les propriétés non reconnues pendant la désérialisation.

Est-ce la même chose qu'une simple propriété vide?

12
rsmets

Réponse courte:

  1. @JsonIgnoreProperties(ignoreUnknown=true) s'applique uniquement à la désérialisation de JSON en Java (POJO). Si votre POJO ne contient pas certaines propriétés que JSON contient, elles sont ignoré et aucune erreur n'est levée.
  2. D'un autre côté, @JsonInclude(Include.NON_EMPTY) est utilisé lors de la sérialisation de POJO en JSON et dit, ignorez les propriétés POJO qui sont:

    null ou ce qui est considéré comme vide ne doivent pas être inclus. La définition du vide est spécifique au type de données.

Longue réponse:

@ JsonInclude

Est utilisé uniquement au moment de la sérialisation. Il indique que si la valeur d'une propriété (ou de toutes les propriétés) en question est égale à une certaine valeur (null, empty - quoi que cela signifie, ou une valeur par défaut) cette propriété n'est pas sérialisée.

Sans cette annotation, la valeur de la propriété est toujours sérialisée. L'annotation permet de réduire le nombre de propriétés transférées (la valeur par défaut de la propriété doit être spécifiée lorsqu'elle n'est pas présente du côté réception).

Exemple:

public class Person {
    public String firstName = "Mark";
    public String middleName;
    public String lastName = "Watney";
}

ObjectMapper mapper = new ObjectMapper();
Person p = new Person();
System.out.println(mapper.writeValueAsString(p));

Produira la sortie suivante:

{"firstName":"Mark","middleName":null,"lastName":"Watney"}

Mais si Person est annoté avec @JsonInclude(Include.NON_EMPTY), middleName est omis de la sortie car sa valeur est "vide" (null dans ce cas):

@JsonInclude(Include.NON_EMPTY)
public static class Person {
    [....]
}

La sortie de la console est: {"firstName":"Mark","lastName":"Watney"}

@ JsonIgnoreProperties

Est utilisé pour ignorer certaines propriétés dans la sérialisation et la désérialisation quelles que soient ses valeurs:

pour empêcher les champs spécifiés d'être sérialisés ou désérialisés (c'est-à-dire ne pas inclure dans la sortie JSON; ou être définis même s'ils ont été inclus): @JsonIgnoreProperties({ "internalId", "secretKey" })

Pour ignorer toutes les propriétés inconnues dans l'entrée JSON sans exception: @JsonIgnoreProperties(ignoreUnknown=true)

Si l'entrée JSON est:

{
    "firstName": "Homer",
    "middleName": "Jay",
    "lastName": "Simpson"
}

Et la classe c'est:

public class Person {
    public String firstName;
    public String lastName;
}

La désérialisation mapper.readValue(json, Person.class) produira UnrecognizedPropertyException exception:

Exception dans le thread "principal" com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: champ non reconnu "middleName" .....

Parce que la propriété middleName ne fait pas partie de la classe Person.

Mais si la classe Person était annotée avec @JsonIgnoreProperties(ignoreUnknown=true), les propriétés inconnues (comme middleName) seraient ignorées lors de la désérialisation en POJO.

@JsonIgnoreProperties(ignoreUnknown=true)
public class person {
    [...]
}

Un autre cas d'utilisation courant consiste à supprimer la sérialisation des propriétés sensibles, comme par exemple le mot de passe:

@JsonIgnoreProperties("password")
public static class User {
    public String login = "simpsonh";
    public String password = "D00nut";
    public String firstName = "Homer";
    public String middleName = "Jay";
    public String lastName = "Simpson";
}

Maintenant, si vous sérialisez la classe User, le mot de passe sera omis de la sortie:

User u = new User();
System.out.println(mapper.writeValueAsString(u));

Sortie console: {"login":"simpsonh","firstName":"Homer","middleName":"Jay","lastName":"Simpson"}

49
Michal Foksa