2011-10-27 13 views
7

Tengo una clase que tiene más de una docena de propiedades. Para la mayoría de las propiedades de tipo primitivo, espero utilizar BeanSerializer y BeanDeserializer por defecto o lo que sea para reducir el engorroso código que necesito escribir. Para otras propiedades de tipos de arreglos y personalizados, quiero hacer un serializador/deserializador personalizado. Tenga en cuenta que no puedo cambiar la cadena JSON subyacente. Pero tengo acceso completo al código de Android. Estoy usando Jackson 1.7.9/Ektorp 1.1.1.¿Cómo escribir un serializador y deserializador personalizado en Jackson?

¿Debería la subclase BeanDeserializer? Estoy teniendo problemas con eso. Espera un constructor predeterminado sin parámetros, pero no sé cómo llamar al super constructor.

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

Busqué en Google pero no encontré ejemplos/tutoriales útiles. Si alguien puede enviarme algunos ejemplos de trabajo, ¡sería genial! ¡Gracias!

Respuesta

4

Para sub-clase BeanSerializer/-Deserializer, sería mejor utilizar una versión más reciente de Jackson, ya que esta área se ha mejorado con soporte explícito a través de BeanSerializerModifier y BeanDeserializerModifier, que puede alterar la configuración de las instancias.

Pero sólo para asegurarse, también puede especificar la costumbre serializador/deserializer sólo ser utilizado en propiedades individuales, así:

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

Gracias por la idea! Lo probaré para ver si funciona. Estoy usando Ektorp para Android y sugieren 1.1.1, por eso estoy usando Jackson 1.7.9. Pero podría funcionar si actualizo. –

+0

la versión más alta que puedo usar es 1.8.5. ¿Cualquier sugerencia? Voy a probar tu idea de JsonSerializer en OddType. –

+0

1.8 tiene mejor capacidad de sobrepaso que 1.7, por lo que podría funcionar. Al usar BeanSerializerModifier, en realidad no tiene que anular BeanSerializer, pero también podría crear instancias personalizadas, pero diferir otros accesorios a las configuraciones predeterminadas. Además, sus serializadores personalizados pueden buscar los predeterminados en el método 'resolve()' (si implementa ResolvableSerializer, de forma similar a como lo hace BeanSerializer). Lo ideal es evitar la subclasificación de BeanSerializers si es posible, solo por simplicidad; pero si necesita subclase, esa es una técnica admitida también. – StaxMan

Cuestiones relacionadas