2011-11-22 10 views
7

C'è un modo per registrare un filtro di proprietà globale in ObjectMapper? Globale significa che sarà applicato a tutti i bean serializzati. Non posso usare annotazioni (non posso modificare i fagioli serializzati) e non so quali proprietà hanno i bean. Il filtro dovrebbe essere basato sul nome.Filtro proprietà globali in Jackson

La mia prima idea era scrivere un serializzatore personalizzato, ma non so cosa dovrei passare al costruttore.

risposta

9

Farei uso di un FilterProvider. È un po 'complicato, ma non troppo ingombrante.

import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility; 
import org.codehaus.jackson.annotate.JsonMethod; 
import org.codehaus.jackson.map.ObjectMapper; 
import org.codehaus.jackson.map.ObjectWriter; 
import org.codehaus.jackson.map.annotate.JsonFilter; 
import org.codehaus.jackson.map.ser.FilterProvider; 
import org.codehaus.jackson.map.ser.impl.SimpleBeanPropertyFilter; 
import org.codehaus.jackson.map.ser.impl.SimpleFilterProvider; 

public class JacksonFoo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    Bar bar = new Bar(); 
    bar.id = "42"; 
    bar.name = "James"; 
    bar.color = "blue"; 
    bar.foo = new Foo(); 
    bar.foo.id = "7"; 
    bar.foo.size = "big"; 
    bar.foo.height = "tall"; 

    ObjectMapper mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY); 
    System.out.println(mapper.writeValueAsString(bar)); 
    // output: 
    // {"id":"42","name":"James","color":"blue","foo":{"id":"7","size":"big","height":"tall"}} 

    String[] ignorableFieldNames = { "id", "color" }; 

    FilterProvider filters = new SimpleFilterProvider().addFilter("filter properties by name", SimpleBeanPropertyFilter.serializeAllExcept(ignorableFieldNames)); 

    mapper = new ObjectMapper().setVisibility(JsonMethod.FIELD, Visibility.ANY); 
    mapper.getSerializationConfig().addMixInAnnotations(Object.class, PropertyFilterMixIn.class); 
    ObjectWriter writer = mapper.writer(filters); 

    System.out.println(writer.writeValueAsString(bar)); 
    // output: 
    // {"name":"James","foo":{"size":"big","height":"tall"}} 
    } 
} 

@JsonFilter("filter properties by name") 
class PropertyFilterMixIn 
{ 

} 

class Bar 
{ 
    String id; 
    String name; 
    String color; 
    Foo foo; 
} 

class Foo 
{ 
    String id; 
    String size; 
    String height; 
} 

Per altri approcci e ulteriori informazioni, consiglio le seguenti risorse.

+0

funziona come un fascino :) Ci sono un sacco di posto per il miglioramento nella documentazione Jackson. – DAN

+0

Per gli interessati, ho registrato una richiesta di miglioramento su http://jira.codehaus.org/browse/JACKSON-724 per semplificare la configurazione necessaria per filtrare le proprietà in base al nome. –

+0

@DAN Assolutamente! I contributi sono SOPRATTUTTO benvenuti per la documentazione! (inclusi collegamenti a buoni articoli, aggiornamenti wiki) – StaxMan