web-dev-qa-db-fra.com

Jackson - Comment spécifier une implémentation unique pour la désérialisation référencée par interface?

Je veux désérialiser un objet JSON avec Jackson. Parce que la cible est une interface, je dois spécifier quelle implémentation doit être utilisée.

Ces informations pourraient être stockées dans l'objet JSON, à l'aide de @ JsonTypeInfo-Annotation. Mais je veux spécifier l'implémentation dans le code source car c'est toujours la même chose.

Est-ce possible?

33
Max Schmidt

Utilisez un SimpleAbstractTypeResolver :

ObjectMapper mapper = new ObjectMapper();

SimpleModule module = new SimpleModule("CustomModel", Version.unknownVersion());

SimpleAbstractTypeResolver resolver = new SimpleAbstractTypeResolver();
resolver.addMapping(Interface.class, Implementation.class);

module.setAbstractTypes(resolver);

mapper.registerModule(module);
34
David Grant

Il existe une autre approche qui fonctionnera si vous n'avez qu'une seule implémentation d'interface.

public class ClassYouWantToDeserialize {
    @JsonDeserialize(as = ImplementationClass.class)
    private InterfaceClass property;
...
}

Cette question a été répondue il y a un certain temps, mais je veux vous donner une autre option qui ne nécessite pas de régler ObjectMapper et aussi beaucoup plus simple que l'annotation @JsonTypeInfo.

22
Ilya Ovesnov

Vous pouvez également utiliser @JsonDeserialize(as = ImplementationClass.class) sur l'interface et toutes les références seront désérialisées de la même manière.

Remarque, si l'une de vos classes d'implémentation est une énumération, vous pourriez également avoir besoin de @JsonFormat(shape = JsonFormat.Shape.OBJECT) sur l'énumération.

6
Jason Smiley