web-dev-qa-db-fra.com

Comment faire pour empêcher les valeurs NULL dans une carte et les champs NULL dans un bean d'être sérialisés via Jackson

J'ai un Map<String,Foo> foosMap que je veux sérialiser par Jackson. Maintenant, je veux suivre deux paramètres sur le processus de sérialisation:

  1. La carte peut avoir beaucoup de valeurs nulles et de clés nulles et je ne veux pas que les valeurs nulles soient sérialisées.
  2. Pour tous les Foos en cours de sérialisation, je ne veux pas sérialiser les objets null référencés dans Foo.

Quel est le meilleur moyen d'y parvenir? J'utilise des jacks jackson-core1.9 et jackson-mapper1.9 dans mon projet. 

43
Inquisitive

S'il est raisonnable de modifier la structure de données Map d'origine pour la sérialiser afin de mieux représenter la valeur réelle que l'on souhaite sérialiser, il s'agit probablement d'une approche décente, ce qui réduirait éventuellement la quantité de configuration de Jackson nécessaire. Par exemple, supprimez si possible les entrées de la clé null avant d'appeler Jackson. Cela dit...


Pour supprimer les entrées Map de sérialisation avec des valeurs NULL:

Avant Jackson 2.9

vous pouvez toujours utiliser WRITE_NULL_MAP_VALUES, mais notez qu'il a été déplacé vers SerializationFeature :

mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);

Depuis Jackson 2.9

Le WRITE_NULL_MAP_VALUES est obsolète, vous pouvez utiliser l'équivalent ci-dessous:

mapper.setDefaultPropertyInclusion(
   JsonInclude.Value.construct(Include.ALWAYS, Include.NON_NULL))

Pour supprimer la sérialisation des propriétés avec des valeurs NULL, vous pouvez configurer la ObjectMapper directement , ou utiliser le @JsonInclude annotation:

mapper.setSerializationInclusion(Include.NON_NULL);

ou:

@JsonInclude(Include.NON_NULL)
class Foo
{
  public String bar;

  Foo(String bar)
  {
    this.bar = bar;
  }
}

Pour gérer les clés null Map, une sérialisation personnalisée est nécessaire, comme je le comprends le mieux. 

Une approche simple pour sérialiser les clés null en tant que chaînes vides (avec des exemples complets des deux configurations mentionnées précédemment):

import Java.io.IOException;
import Java.util.HashMap;
import Java.util.Map;

import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;

public class JacksonFoo
{
  public static void main(String[] args) throws Exception
  {
    Map<String, Foo> foos = new HashMap<String, Foo>();
    foos.put("foo1", new Foo("foo1"));
    foos.put("foo2", new Foo(null));
    foos.put("foo3", null);
    foos.put(null, new Foo("foo4"));

    // System.out.println(new ObjectMapper().writeValueAsString(foos));
    // Exception: Null key for a Map not allowed in JSON (use a converting NullKeySerializer?)

    ObjectMapper mapper = new ObjectMapper();
    mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);
    mapper.setSerializationInclusion(Include.NON_NULL);
    mapper.getSerializerProvider().setNullKeySerializer(new MyNullKeySerializer());
    System.out.println(mapper.writeValueAsString(foos));
    // output: 
    // {"":{"bar":"foo4"},"foo2":{},"foo1":{"bar":"foo1"}}
  }
}

class MyNullKeySerializer extends JsonSerializer<Object>
{
  @Override
  public void serialize(Object nullKey, JsonGenerator jsonGenerator, SerializerProvider unused) 
      throws IOException, JsonProcessingException
  {
    jsonGenerator.writeFieldName("");
  }
}

class Foo
{
  public String bar;

  Foo(String bar)
  {
    this.bar = bar;
  }
}

Pour supprimer la sérialisation des entrées Map avec les clés null, un traitement de sérialisation personnalisé supplémentaire est nécessaire.

101
Programmer Bruce

Pour les versions de Jackson <2.0, utilisez cette annotation sur la classe en cours de sérialisation:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
19
AllBlackt

La réponse semble être un peu ancienne. Ce que j’ai fait est d’utiliser ce mappeur pour convertir une MAP

      ObjectMapper mapper = new ObjectMapper().configure(SerializationConfig.Feature.WRITE_NULL_MAP_VALUES, false);

une simple Map:

          Map<String, Object> user = new HashMap<String,Object>();
            user.put( "id",  teklif.getAccount().getId() );
            user.put( "fname", teklif.getAccount().getFname());
            user.put( "lname", teklif.getAccount().getLname());
            user.put( "email", teklif.getAccount().getEmail());
            user.put( "test", null);

Utilisez-le comme ceci par exemple:

      String json = mapper.writeValueAsString(user);
3
azerafati

ma solution, espérons l'aide 
ObjectMapper personnalisé et config à spring xml (enregistrer les conveters de message)

public class PyResponseConfigObjectMapper extends ObjectMapper {
public PyResponseConfigObjectMapper() {
    disable(SerializationFeature.WRITE_NULL_MAP_VALUES); //map no_null
    setSerializationInclusion(JsonInclude.Include.NON_NULL); // bean no_null
}

}

0
oneyoungping