web-dev-qa-db-fra.com

Sérialisation Jackson: ignorer les valeurs vides (ou null)

J'utilise actuellement Jackson 2.1.4 et j'ai du mal à ignorer les champs lorsque je convertis un objet en chaîne JSON.

Voici ma classe qui agit comme objet à convertir:

public class JsonOperation {

public static class Request {
    @JsonInclude(Include.NON_EMPTY)
    String requestType;
    Data data = new Data();

    public static class Data {
        @JsonInclude(Include.NON_EMPTY)
        String username;
        String email;
        String password;
        String birthday;
        String coinsPackage;
        String coins;
        String transactionId;
        boolean isLoggedIn;
    }
}

public static class Response {
    @JsonInclude(Include.NON_EMPTY)
    String requestType = null;
    Data data = new Data();

    public static class Data {
        @JsonInclude(Include.NON_EMPTY)
        enum ErrorCode { ERROR_INVALID_LOGIN, ERROR_USERNAME_ALREADY_TAKEN, ERROR_EMAIL_ALREADY_TAKEN };
        enum Status { ok, error };

        Status status;
        ErrorCode errorCode;
        String expiry;
        int coins;
        String email;
        String birthday;
        String pictureUrl;
        ArrayList <Performer> performer;
    }
}
}

Et voici comment je le convertis:

ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.FIELD, Visibility.ANY);

JsonOperation subscribe = new JsonOperation();

subscribe.request.requestType = "login";

subscribe.request.data.username = "Vincent";
subscribe.request.data.password = "test";


Writer strWriter = new StringWriter();
try {
    mapper.writeValue(strWriter, subscribe.request);
} catch (JsonGenerationException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (JsonMappingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
} catch (IOException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}

Log.d("JSON", strWriter.toString())

Voici la sortie:

{"data":{"birthday":null,"coins":null,"coinsPackage":null,"email":null,"username":"Vincent","password":"test","transactionId":null,"isLoggedIn":false},"requestType":"login"}

Comment puis-je éviter ces valeurs nulles? Je veux seulement prendre les informations requises pour le but "d'abonnement"!

Voici exactement le résultat que je recherche:

{"data":{"username":"Vincent","password":"test"},"requestType":"login"}

J'ai également essayé @JsonInclude (Include.NON_NULL) et mis toutes mes variables à null, mais cela n'a pas fonctionné non plus! Merci pour votre aide les gars!

128
Shinnyx

L'annotation est au mauvais endroit - elle doit être sur la classe, pas sur le terrain. c'est à dire:

@JsonInclude(Include.NON_NULL) //or Include.NON_EMPTY, if that fits your use case 
public static class Request {
  // ...
}

Comme indiqué dans les commentaires, dans la version 2.x +, la syntaxe de cette annotation est la suivante:

@JsonSerialize(include = JsonSerialize.Inclusion.NON_NULL) // or JsonSerialize.Inclusion.NON_EMPTY

L’autre option consiste à configurer le ObjectMapper directement, simplement en appelant mapper.setSerializationInclusion(Include.NON_NULL);

(pour mémoire, je pense que la popularité de cette réponse est une indication que cette annotation devrait soit applicable champ par champ * ahem @ plus rapide *.)

226
awqueous

Vous pouvez également définir l'option globale:

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
44
nomad

Aussi, vous pouvez essayer d'utiliser

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)

si vous avez affaire à jackson avec une version inférieure à 2+ (1.9.5) je l’ai testée, vous pouvez facilement utiliser cette annotation au-dessus de la classe. Pas pour spécifié pour les attributs, juste pour la décélération de classe.

15
erhanasikoglu

Vous devez ajouter import com.fasterxml.jackson.annotation.JsonInclude;

Ajouter

@JsonInclude(JsonInclude.Include.NON_NULL)

au sommet de POJO

Si vous avez imbriqué POJO alors

@JsonInclude(JsonInclude.Include.NON_NULL)

besoin d'ajouter toutes les valeurs.

REMARQUE: JAXRS (Jersey) gère automatiquement ce scénario 2.6 et supérieur.

12
vaquar khan

Pour jackson 2.x

@JsonInclude (JsonInclude.Include.NON_NULL) juste avant le champ.

3
Gere

J'avais un problème similaire récemment avec la version 2.6.6.

@JsonInclude(JsonInclude.Include.NON_NULL)

L’utilisation des annotations ci-dessus au niveau du fichier ou de la classe ne fonctionnait pas comme prévu. Le POJO était modifiable lorsque j'appliquais l'annotation. Lorsque j'ai modifié le comportement du POJO pour qu'il soit immuable, l'annotation a fonctionné de manière magique.

Je ne sais pas si sa version précédente ou les versions précédentes de cette bibliothèque avaient un comportement similaire, mais pour 2.6.6, vous devez certainement disposer de POJO immuable pour que l'annotation fonctionne.

objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

L'option ci-dessus mentionnée dans diverses réponses sur la définition de l'inclusion de la sérialisation dans ObjectMapper directement au niveau global fonctionne également, mais je préfère le contrôler au niveau classe ou fichier.

Ainsi, si vous souhaitez que tous les champs nuls soient ignorés lors de la sérialisation JSON, utilisez l'annotation au niveau de la classe, mais si vous ne souhaitez ignorer que quelques champs dans une classe, utilisez-le sur ces champs spécifiques. De cette façon, il est plus facile à lire et à utiliser pour la maintenance si vous souhaitez modifier le comportement d’une réponse spécifique.

2
Amrut

Ou vous pouvez utiliser GSON [ https://code.google.com/p/google-gson/ ], où ces champs nuls seront automatiquement supprimés.

SampleDTO.Java

public class SampleDTO {

    String username;
    String email;
    String password;
    String birthday;
    String coinsPackage;
    String coins;
    String transactionId;
    boolean isLoggedIn;

    // getters/setters
}

Test.Java

import com.google.gson.Gson;

public class Test {

    public static void main(String[] args) {
        SampleDTO objSampleDTO = new SampleDTO();
        Gson objGson = new Gson();
        System.out.println(objGson.toJson(objSampleDTO));
    }
}

SORTIE:

{"isLoggedIn":false}

J'ai utilisé gson-2.2.4

2
anij

Le code ci-dessous peut être utile si vous souhaitez exclure le type booléen de la sérialisation:

@JsonInclude(JsonInclude.Include.NON_ABSENT)
0
Alexander