How to write custom serializer and deserializer in Jackson?

PokerIncome.com picture PokerIncome.com · Oct 28, 2011 · Viewed 9.6k times · Source

I have a class that has more than a dozen properties. For most of the properties of primitive type, I hope to use the default BeanSerializer and BeanDeserializer or whatever to reduce the cumbersome code I need to write. For other properties of custom and array types, I want to do some custom serializer/deserializer. Note that I am not able to change the underlying JSON string. But I have full access to the android code. I am using Jackson 1.7.9/Ektorp 1.1.1.

shall I subclass BeanDeserializer? I am having trouble with that. It expects a default constructor with no parameters but I don't know how to call the 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;
}
}

I searched Google but couldn't find any helpful examples/tutorial. If anyone can send me some working examples that would be great! Thanks!

Answer

StaxMan picture StaxMan · Oct 28, 2011

To sub-class BeanSerializer/-Deserializer, you would be better off using a more recent version of Jackson, since this area has been improved with explicit support via BeanSerializerModifier and BeanDeserializerModifier, which can alter configuration of instances.

But just to make sure, you can also specify custom serializer/deserializer to just be used on individual properties, like so:

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