Comment empêcher les valeurs nulles à L'intérieur d'une Map et les champs null à l'intérieur D'un bean d'être sérialisés par Jackson

j'ai un a Map<String,Foo> foosMap que je veux sérialiser à travers Jackson . Maintenant je veux les deux paramètres suivants sur le processus de sérialisation:

  1. la carte peut avoir beaucoup de valeurs nulles et de touches nulles et je ne veux pas que nulls soit sérialisé.
  2. pour tous les Foos qui sont sérialisés, Je ne veux pas sérialiser les objets nuls référencés dans Foo.

Quelle est la meilleure façon d'atteindre cette ? J'utilise jackson-core1.9 et jackson-mapper1.9 pots dans mon projet.

40
demandé sur Programmer Bruce 2012-07-12 13:47:59

4 réponses

S'il est raisonnable de modifier la structure de données originale Map pour être sérialisé afin de mieux représenter la valeur réelle désirée pour être sérialisé, c'est probablement une approche décente, ce qui pourrait réduire la quantité de configuration de Jackson nécessaire. Par exemple, supprimez simplement les entrées clés null , si possible, avant D'appeler Jackson. Qui a dit...


supprimer les entrées en série Map avec null valeurs:

Avant Jackson 2.9

vous pouvez toujours utiliser WRITE_NULL_MAP_VALUES , mais notez qu'il est déplacé à SerializationFeature :

mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false);

Depuis Jackson 2.9

le WRITE_NULL_MAP_VALUES est déprécié, vous pouvez utiliser l'équivalent ci-dessous:

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

pour supprimer sérialiser les propriétés avec des valeurs nulles, vous pouvez configurer le 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 manipuler les clés null Map , une sérialisation personnalisée est nécessaire, du mieux que je comprenne.

une approche simple pour sérialiser les touches null comme vides chaînes (y compris 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 les entrées de sérialisation Map avec les touches null , il faudrait procéder à une nouvelle sérialisation personnalisée.

94
répondu Programmer Bruce 2018-01-13 08:37:13

Pour Jackson versions < 2.0 utiliser cette annotation sur la classe d'être sérialisé:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
18
répondu AllBlackt 2016-04-22 20:17:23

la réponse semble un peu vieille, ce que j'ai fait était d'utiliser ce mapper pour convertir un MAP

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

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
répondu azerafati 2014-09-04 07:57:35

ma solution, l'espoir d'aider

personnalisé ObjectMapper et de configuration de spring xml(message registre conveters)

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
répondu oneyoungping 2017-04-17 07:20:08