117 votes

Définition de valeurs par défaut pour les champs nuls lors du mappage avec Jackson

J'essaie de faire correspondre certains objets JSON à des objets Java avec Jackson. Certains des champs de l'objet JSON sont obligatoires (ce que je peux marquer avec @NotNull ) et certains sont facultatifs.

Après le mappage avec Jackson, tous les champs qui ne sont pas définis dans l'objet JSON auront une valeur nulle en Java. Existe-t-il une annotation similaire à @NotNull qui peut dire à Jackson de donner une valeur par défaut à un membre d'une classe Java, au cas où il serait nul ?

Modifier : Pour rendre la question plus claire, voici un exemple de code.

L'objet Java :

class JavaObject {
    @NotNull
    public String notNullMember;

    @DefaultValue("Value")
    public String optionalMember;
}

L'objet JSON peut être soit :

{
    "notNullMember" : "notNull"
}

ou :

{
    "notNullMember" : "notNull",
    "optionalMember" : "optional"
}

En @DefaultValue Les annotations sont juste pour montrer ce que je demande. Il ne s'agit pas d'une véritable annotation. Si l'objet JSON est comme dans le premier exemple, je veux la valeur de l'annotation optionalMember à être "Value" et non null . Existe-t-il une annotation qui fasse une telle chose ?

110voto

Ilya Points 12449

Il n'y a pas d'annotation pour définir la valeur par défaut.
Vous pouvez définir la valeur par défaut uniquement au niveau de la classe java :

public class JavaObject 
{
    public String notNullMember;

    public String optionalMember = "Value";
}

54voto

Sergey Voitovich Points 748

Une seule solution proposée permet de conserver le default-value quand some-value:null a été défini explicitement (la lisibilité des POJO est perdue et c'est maladroit).

Voici comment on peut garder le default-value et ne jamais le mettre sur null

@JsonProperty("some-value")
public String someValue = "default-value";

@JsonSetter("some-value")
public void setSomeValue(String s) {
    if (s != null) { 
        someValue = s; 
    }
}

18voto

SPidey Points 11

Utilisez le JsonSetter avec la valeur Nulls.SKIP

Si vous voulez attribuer une valeur par défaut à un paramètre qui n'est pas défini dans la requête json, vous pouvez simplement l'attribuer dans le POJO lui-même.

Si vous n'utilisez pas @JsonSetter(nulls = Nulls.SKIP) alors la valeur par défaut sera initialisée uniquement si aucune valeur n'est fournie dans le JSON, mais si quelqu'un met explicitement un null, cela peut conduire à un problème. Utilisation de @JsonSetter(nulls = Nulls.SKIP) indiquera au dé-séparateur de Json d'éviter null l'initialisation.

Valeur qui indique qu'une valeur nulle en entrée doit être ignorée et que l'affectation par défaut doit être effectuée ; cela signifie généralement que la propriété aura sa valeur par défaut .

comme suit :

public class User {
    @JsonSetter(nulls = Nulls.SKIP)
    private Integer Score = 1000;
    ...
}

11voto

Jagadish Points 11

Il existe une solution, si vous utilisez l'annotation Builder de lombok,

"@Builder.default" sur la propriété. par exemple.

@Value
@Builder
@Jacksonized
public class SomeClass {

     String field1;

     @Builder.default
     String field2 = "default-value";

}

Ainsi, dans la requête json entrante, si le champ2 n'est pas spécifié, l'annotation Builder.default permettra à l'interface Builder de définir la valeur par défaut spécifiée dans la propriété, sinon, la valeur originale de la requête sera définie dans cette propriété.

9voto

Pau Points 4642

Vous pouvez créer votre propre JsonDeserializer et annoter cette propriété avec @JsonDeserialize(as = DefaultZero.class)

Par exemple : Pour configurer BigDecimal pour que la valeur par défaut soit ZERO :

public static class DefaultZero extends JsonDeserializer<BigDecimal> {
    private final JsonDeserializer<BigDecimal> delegate;

    public DefaultZero(JsonDeserializer<BigDecimal> delegate) {
        this.delegate = delegate;
    }

    @Override
    public BigDecimal deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException {
        return jsonParser.getDecimalValue();
    }

    @Override
    public BigDecimal getNullValue(DeserializationContext ctxt) throws JsonMappingException {
        return BigDecimal.ZERO;
    }
}

Et l'usage :

class Sth {

   @JsonDeserialize(as = DefaultZero.class)
   BigDecimal property;
 }

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