2011-10-27 10 views
7

Ho una classe che ha più di una dozzina di proprietà. Per la maggior parte delle proprietà di tipo primitivo, spero di utilizzare il BeanSerializer e BeanDeserializer di default o qualsiasi altra cosa per ridurre il codice ingombrante che ho bisogno di scrivere. Per altre proprietà di tipi personalizzati e array, voglio fare un serializzatore/deserializzatore personalizzato. Si noti che non sono in grado di modificare la stringa JSON sottostante. Ma ho pieno accesso al codice di Android. Sto usando Jackson 1.7.9/Ektorp 1.1.1.Come scrivere serializzatori e deserializzatori personalizzati in Jackson?

devo sottoclasse BeanDeserializer? Sto avendo problemi con questo. Si aspetta un costruttore predefinito senza parametri, ma non so come chiamare il super costruttore.

class MyType{ 
    // a dozen properties with primitive types String, Int, BigDecimal 
    public Stirng getName(); 
    public void setName(String name); 

    // properties that require custom deserializer/serializer 
    public CustomType getCustom(); 
    public void setCustom(CustomType ct); 
} 

class MyDeserializer extends BeanDeserialzer{ 
    // an exception is throw if I don't have default constructor. 
    // But BeanDeserializer doesn't have a default constructor 
    // It has the below constructor that I don't know how to fill in the parameters 
    public MyDeserializer(AnnotatedClass forClass, JavaType type, 
     BeanProperty property, CreatorContainer creators, 
     BeanPropertyMap properties, 
     Map<String, SettableBeanProperty> backRefs, 
     HashSet<String> ignorableProps, boolean ignoreAllUnknown, 
     SettableAnyProperty anySetter) { 
    super(forClass, type, property, creators, properties, backRefs, ignorableProps, 
      ignoreAllUnknown, anySetter); 
} 
    @Override 
    public Object deserialize(JsonParser jp, DeserializationContext dc, Object bean) 
     throws IOException, JsonProcessingException { 
    super.deserialize(jp, dc, bean); 
     MyType c = (MyType)bean;   

      ObjectMapper mapper = new ObjectMapper(); 

      JsonNode rootNode = mapper.readValue(jp, JsonNode.class); 
      // Use tree model to construct custom 
      // Is it inefficient because it needs a second pass to the JSON string to construct the tree? 
      c.setCustom(custom); 
      return c; 
} 
} 

Ho cercato su Google ma non ho trovato alcun utile esempio/tutorial. Se qualcuno può inviarmi alcuni esempi di lavoro che sarebbe fantastico! Grazie!

risposta

4

Per sottoclasse BeanSerializer/-Deserializer, sarebbe meglio utilizzare una versione più recente di Jackson, poiché quest'area è stata migliorata con il supporto esplicito tramite BeanSerializerModifier e BeanDeserializerModifier, che possono alterare la configurazione delle istanze.

Ma solo per assicurarsi che, è anche possibile specificare personalizzato serializzatore/deserializzatore per essere usato solo su singole proprietà, in questo modo:

class Foo { 
    @JsonSerialize(using=MySerializer.class) 
    public OddType getValue(); 
} 
+0

Grazie per l'idea! Lo proverò per vedere se funziona. Sto usando Ektorp per Android e suggeriscono 1.1.1, ecco perché sto usando Jackson 1.7.9. Ma potrebbe funzionare se aggiorno. –

+0

la versione più alta che posso andare è 1.8.5. Qualche suggerimento? Proverò la tua idea JsonSerializer su OddType. –

+0

1.8 ha una migliore sovrascrittura di 1.7 quindi potrebbe effettivamente funzionare. Usando BeanSerializerModifier non devi in ​​alcun modo sovrascrivere BeanSerializer, ma potresti anche creare istanze personalizzate, ma rimandare altri oggetti di scena alle impostazioni predefinite. Inoltre, i serializzatori personalizzati possono cercare quelli predefiniti nel metodo 'resolve()' (se si implementa ResolvableSerializer, in modo simile a come fa BeanSerializer). Idealmente eviteresti di classificare i BeanSerializer se possibile, solo per semplicità; ma se hai bisogno di sottoclasse, anche questa è una tecnica supportata. – StaxMan