2012-07-12 17 views
39

Ho un Map<String,Foo> foosMap che desidero serializzare tramite Jackson. Ora voglio seguire due impostazioni sul processo di serializzazione:Come impedire che valori null all'interno di una mappa e campi null all'interno di un bean vengano serializzati tramite Jackson

  1. La mappa può avere un sacco di valori nulli e chiavi null e non voglio che i numeri nulli siano serializzati.
  2. Per tutti quei dischi che vengono serializzati, non desidero serializzare oggetti nulli referenziati all'interno di Foo.

Qual è il modo migliore per raggiungere questo obiettivo? Sto usando i jacks di jackson-core1.9 e jackson-mapper1.9 nel mio progetto.

+0

Possibile duplicato, si prega di controllare questo link: http://stackoverflow.com/questions/3140563/how-to-avoi d-null-values-serialization-in-hashmap – dbf

+0

La mappa può avere almeno una chiave nulla – amicngh

+0

@dbf non del tutto. per favore guarda di nuovo il titolo della domanda modificato. – Inquisitive

risposta

91

Se è ragionevole modificare la struttura di dati originale di Map per la serializzazione per rappresentare meglio il valore effettivo che si desidera serializzare, è probabilmente un approccio decente, che potrebbe ridurre la quantità di configurazione di Jackson necessaria. Ad esempio, è sufficiente rimuovere le voci chiave null, se possibile, prima di chiamare Jackson. Detto questo ...


Per sopprimere la serializzazione Map voci con valori nulli:

Prima di Jackson 2.9

si può ancora fare uso di WRITE_NULL_MAP_VALUES, ma nota che è spostato a SerializationFeature:

mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); 

Dal Jackson 2.9

Il WRITE_NULL_MAP_VALUES è deprecato, è possibile utilizzare l'equivalente di seguito:

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

Per sopprimere la serializzazione di proprietà con valori nulli, è possibile configure the ObjectMapper directly, o usufruire del @JsonInclude della nota:

mapper.setSerializationInclusion(Include.NON_NULL); 

oppure:

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

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

Per gestire nulli Map chiavi, alcuni serializzazione personalizzata è necessario, come meglio ho capito.

Un approccio semplice per serializzare null chiavi come stringhe vuote (compresi esempi completi delle due configurazioni precedentemente menzionati):

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; 
    } 
} 

per sopprimere la serializzazione Map voci con null tasti, elaborazione serializzazione ulteriormente personalizzato sarebbe necessario.

+2

Solo un avvertimento queste direzioni sono specifiche di Jackson 2.0 ('com.fasterxml' vs' org.codehaus'). –

+0

@ProgrammerBruce - È possibile impedire la serializzazione del campo nullo per una classe specifica nel mappatore oggetti? es .: utilizzare lo stesso mappatore di oggetti per serializzare le classi A e B, ma solo i campi null nella classe B vengono ignorati. – ThatGuyGrant

+0

@ProgrammerBurce - poiché il jackson è aggiornato a 2.9, WRITE_NULL_MAP_VALUES è obsoleto. Sai c'è un modo alternativo per fare lo stesso? –

18

Per versioni Jackson < 2.0 utilizzare questa annotazione sulla classe di essere serializzato:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 
+1

FYI, questo è obsoleto, la risposta accettata sopra ha l'ultima annotazione: @JsonInclude (Include.NON_NULL) – Amber

+0

Si noti che l'annotazione JsonInclude non è disponibile se si utilizza Jackson 1.9.x, nel qual caso sarà necessario utilizzare l'annotazione JsonSerialize. –

+0

Confermo con Jackson 1.9.x il @JsonInclude (Include.NON_NULL) non funziona. Sto importando questo pacchetto: org.codehaus.jackson.map – Emanuele

3

risposta sembra essere un po 'vecchia, Quello che ho fatto è stato quello di utilizzare questo mapper per convertire un MAP

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

un semplice 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); 

Utilizzare in questo modo, ad esempio:

 String json = mapper.writeValueAsString(user); 
0

la mia soluzione, la speranza di aiuto
personalizzato ObjectMapper e configurazione alla primavera xml (registro conveters messaggi)

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

}

Problemi correlati