web-dev-qa-db-fra.com

Pourquoi Jackson sérialise-t-il également un membre transitoire?

Je sérialise un POJO en JSON en utilisant Jackson 2.1.4 mais je veux ignorer qu'un champ particulier ne soit sérialisé. J'ai utilisé des transitoires mais il sérialise toujours cet élément.

public class TestElement {

    int x;

    private transient String y;

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public String getY() {
        return y;
    }

    public void setY(String y) {
        this.y = y;
    }
}

Je sérialise comme suit:

public static void main(String[] args) throws JsonProcessingException {
    TestElement testElement = new TestElement();
    testElement.setX(10);
    testElement.setY("adasd");
    ObjectMapper om = new ObjectMapper();
    String serialized = om.writeValueAsString(testElement);
    System.err.println(serialized);
}

Veuillez ne pas suggérer @JsonIgnore car je ne veux pas lier mon modèle à des annotations spécifiques à jackson. Peut-on le faire en utilisant uniquement des transitoires? Existe-t-il une API sur objectmapper pour les paramètres de visibilité?

29
Naman

La raison pour laquelle Jackson sérialise le membre transient est parce que les getters sont utilisés pour déterminer ce qu'il faut sérialiser, pas le membre lui-même - et puisque y a un getter public, qui est sérialisé. Si vous souhaitez modifier cette valeur par défaut et que Jackson utilise des champs - faites simplement:

om.setVisibilityChecker(
om.getSerializationConfig().
getDefaultVisibilityChecker().
withFieldVisibility(JsonAutoDetect.Visibility.ANY).
withGetterVisibility(JsonAutoDetect.Visibility.NONE));

Une autre façon d'ignorer une propriété sur la sérialisation est de le faire directement sur la classe:

@JsonIgnoreProperties(value = { "y" })
public class TestElement {
...

Et une autre façon est directement sur le terrain:

public class TestElement {

    @JsonIgnore
    private String y;
...

J'espère que cela t'aides.

48
Eugen

Une nouvelle façon d'empêcher Jackson de sérialiser et de désérialiser est d'appeler mapper.configure(MapperFeature.PROPAGATE_TRANSIENT_MARKER, true).

25
manuel

Je ne peux pas faire de commentaires alors complétez la réponse précédente ici, en changeant la méthode (maintenant) obsolète setVisibilityChecker et en ajoutant une clause manquante pour les booléens:

mapper.setVisibility(
    mapper.getSerializationConfig().
    getDefaultVisibilityChecker().
    withFieldVisibility(JsonAutoDetect.Visibility.ANY).
    withGetterVisibility(JsonAutoDetect.Visibility.NONE).
    withIsGetterVisibility(JsonAutoDetect.Visibility.NONE)
);
3
idelvall