3 votes

Comment forcer Jackson à utiliser les setters d'un objet ?

Étant donné que j'ai le fichier JSON suivant:

{
    "cleanup": false,
    "clearCache": false
}

et le bean suivant:

import org.apache.commons.lang3.Validate;
import com.fasterxml.jackson.annotation.JsonProperty;

public class Config implements IHoldConfiguration {

    public static final boolean DEFAULT_CLEANUP = false;
    public static final boolean DEFAULT_CLEAR_CACHE = false;
    public static final int DEFAULT_CONCURRENCY = 1;

    @JsonProperty(value = "cleanup", required = false, defaultValue = "false")
    private Boolean cleanup;

    @JsonProperty(value = "clearCache", required = false, defaultValue = "false")
    private Boolean clearCache;

    @JsonProperty(value = "concurrency", required = false, defaultValue = "1")
    private Integer concurrency;

    public boolean isCleanup() {
        return this.cleanup.booleanValue();
    }

    public void setCleanup(final Boolean cleanup) {
        this.cleanup = cleanup != null ? cleanup : DEFAULT_CLEANUP;
    }

    public boolean isClearCache() {
        return this.clearCache.booleanValue();
    }

    public void setClearCache(final Boolean clearCache) {
        this.clearCache = clearCache != null ? clearCache : DEFAULT_CLEAR_CACHE;
    }

    public int getConcurrency() {
        return this.concurrency.intValue();
    }

    public void setConcurrency(Integer concurrency) {

        if (concurrency == null) {
            concurrency = DEFAULT_CONCURRENCY;
        } else {
            Validate.inclusiveBetween(1, Integer.MAX_VALUE, concurrency,
                    String.format("concurrency must be in range [1, %s]", Integer.MAX_VALUE));
        }

        this.concurrency = concurrency;
    }
}

Comment puis-je forcer Jackson 2.9.2 à utiliser mon setter concurrency? Actuellement, lors de la désérialisation du JSON vers le bean en utilisant new ObjectMapper().readValue(inputStream, Config.class), concurrency est défini sur null.

Je pensais que Jackson utilisait les setters dans un bean, si fournis, pour définir une propriété. Après avoir vu le résultat désérialisé et débogué, j'ai découvert que ce n'était pas vrai. Puisque l'attribut defaultValue de JsonProperty est uniquement à des fins de documentation, je pensais que je pourrais ajouter le réglage de la valeur par défaut dans les setters, mais évidemment cela n'a pas fonctionné. Comment puis-je accomplir cela?

4voto

Evan Jones Points 556

Le problème est que puisque la concurrence n'est pas déclarée dans votre chaîne JSON, le setter n'est pas appelé. Si vous aviez

{
    cleanup: false,
    clearCache: false,
    concurrency: null
}

Alors le setter serait appelé avec un argument null et vous pourriez définir votre valeur par défaut.

Pour obtenir une valeur par défaut sans modifier la chaîne JSON, vous pourriez faire quelques choses. Tout d'abord, vous pouvez simplement définir la valeur par défaut sur la variable lors de sa déclaration :

public class Config implements IHoldConfiguration {
    ...
    public static final int DEFAULT_CONCURRENCY = 1;

    ...
    private Integer concurrency = Integer.valueOf(DEFAULT_CONCURRENCY);

Maintenant, peu importe que Jackson n'essaie pas de définir la concurrence car elle sera déjà construite avec la valeur correcte. Alternativement, vous pourriez forcer Jackson à utiliser un constructeur et il transmettra toutes les valeurs même celles qui ne sont pas dans la chaîne JSON.

Par exemple, vous pourriez ajouter un constructeur comme suit :

@JsonCreator
public Config (@JsonProperty("cleanup") Boolean cleanup,
               @JsonProperty("clearCache") Boolean clearCache,
               @JsonProperty("concurrency") Integer concurrency) {
    ....

Et y mettre votre logique.

2voto

StaxMan Points 34626

Vous ne pouvez pas le forcer à être appelé car il n'y a rien à l'appeler.

La méthode habituelle pour définir des valeurs par défaut est soit d'assigner directement une valeur au champ lors de la déclaration, comme par exemple :

private Integer concurrence = Integer.valueOf(1);

ou de le faire dans le constructeur par défaut.

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