Je souhaite sérialiser et désérialiser un object immuable à l’aide de com.fasterxml.jackson.databind.ObjectMapper.
La classe immuable ressemble à ceci (seulement 3 atsortingbuts internes, getters et constructeurs):
public final class ImportResultItemImpl implements ImportResultItem { private final ImportResultItemType resultType; private final Ssortingng message; private final Ssortingng name; public ImportResultItemImpl(Ssortingng name, ImportResultItemType resultType, Ssortingng message) { super(); this.resultType = resultType; this.message = message; this.name = name; } public ImportResultItemImpl(Ssortingng name, ImportResultItemType resultType) { super(); this.resultType = resultType; this.name = name; this.message = null; } @Override public ImportResultItemType getResultType() { return this.resultType; } @Override public Ssortingng getMessage() { return this.message; } @Override public Ssortingng getName() { return this.name; } }
Cependant, lorsque je lance ce test unitaire:
@Test public void testObjectMapper() throws Exception { ImportResultItemImpl originalItem = new ImportResultItemImpl("Name1", ImportResultItemType.SUCCESS); Ssortingng serialized = new ObjectMapper().writeValueAsSsortingng((ImportResultItemImpl) originalItem); System.out.println("serialized: " + serialized); //this line will throw exception ImportResultItemImpl deserialized = new ObjectMapper().readValue(serialized, ImportResultItemImpl.class); }
Je reçois cette exception:
com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class eu.ibacz.pdkd.core.service.importcommon.ImportResultItemImpl]: can not instantiate from JSON object (missing default constructor or creator, or perhaps need to add/enable type information?) at [Source: {"resultType":"SUCCESS","message":null,"name":"Name1"}; line: 1, column: 2] at ... nothing interesting here
Cette exception me demande de créer un constructeur par défaut, mais ceci est un object immuable, donc je ne veux pas l’avoir. Comment définirait-il les atsortingbuts internes? Cela perturberait totalement l’utilisateur de l’API.
Donc ma question est la suivante: puis-je en quelque sorte / sérialiser des objects immuables sans constructeur par défaut?
Pour que Jackson sache comment créer un object pour la désérialisation, utilisez les annotations @JsonCreator
et @JsonProperty
pour vos constructeurs, comme ceci:
@JsonCreator public ImportResultItemImpl(@JsonProperty("name") Ssortingng name, @JsonProperty("resultType") ImportResultItemType resultType, @JsonProperty("message") Ssortingng message) { super(); this.resultType = resultType; this.message = message; this.name = name; }
Vous pouvez utiliser un constructeur privé par défaut, Jackson remplira alors les champs par reflection même s’ils sont privés finaux.
EDIT: Et utilisez un constructeur protégé / protégé par défaut pour les classes parentes si vous avez un inheritance.