7 votes

Comment écrire un serializer et deserializer personnalisé dans Jackson ?

J'ai une classe qui a plus d'une douzaine de propriétés. Pour la plupart des propriétés de type primitif, j'espère utiliser le BeanSerializer et le BeanDeserializer par défaut ou autre pour réduire le code lourd que je dois écrire. Pour les autres propriétés de type personnalisé et tableau, je veux utiliser un sérialiseur/désérialiseur personnalisé. Notez que je ne suis pas en mesure de modifier la chaîne JSON sous-jacente. Mais j'ai un accès complet au code Android. J'utilise Jackson 1.7.9/Ektorp 1.1.1.

Dois-je sous-classer BeanDeserializer ? J'ai des difficultés avec cette classe. Il attend un constructeur par défaut sans paramètres, mais je ne sais pas comment appeler le super constructeur.

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

J'ai fait des recherches sur Google, mais je n'ai pas trouvé d'exemples/tutoriels utiles. Si quelqu'un peut m'envoyer des exemples fonctionnels, ce serait formidable ! Merci.

4voto

StaxMan Points 34626

Pour sous-classer BeanSerializer/-Deserializer, il est préférable d'utiliser une version plus récente de Jackson, car ce domaine a été amélioré par un support explicite via BeanSerializerModifier et BeanDeserializerModifier, qui peuvent modifier la configuration des instances.

Mais juste pour être sûr, vous pouvez également spécifier un sérialiseur/désérialiseur personnalisé à utiliser uniquement sur les propriétés individuelles, comme suit :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X