Ho un problema con il mixin e l'ereditarietà di Jackson. Ho due classi target, un genitore e un bambino. Per queste due classi di destinazione ho definito due classi MixIn (interfacce) senza relazione di ereditarietà. Ho anche provato con un'interfaccia MixIn che estendeva l'altra ma non c'era alcuna differenza nel risultato. Quando Jackson serializza la classe genitore usa il mixin correttamente definito per la configurazione di serializzazione e tutto funziona bene. Tuttavia, quando Jackson serializza la classe figlia, userà le definizioni di mixin della classe genitore per serializzare le proprietà che esistono sia nella classe genitore che nella classe figlio. Quindi utilizza le definizioni di mixin classe figlio per serializzare le proprietà definite nella classe figlio ma non nella classe genitore. Ora questo probabilmente ha qualcosa a che fare con il confronto delle classi base o l'implementazione di interfacce in Jackson.Jackson mixin selection and inheritance
Ora la domanda è: esiste un modo in cui io possa istruire Jackson a utilizzare solo le definizioni di mixin per la classe figlio durante la serializzazione di oggetti della classe figlio? E sì, vorrei mantenere entrambe le definizioni del mixin in atto per due casi d'uso separati, quindi rimuovere la mappatura del mixin della classe genitore non risolverà il mio problema.
Esempio di codice e JSON di output previsto ed effettivo di seguito.
Ambiente: versione Jackson versione 2.1.4 Tomcat 7.0.34.0
classi di destinazione e interfacce attuano:
public interface TestI {
public String getName();
}
public interface TestExtendI extends TestI {
public Integer getAge();
}
public class Test implements TestI {
String name;
public Test(String name) {
this.name = name;
}
@Override
public String getName() {
return name;
}
}
public class TestExtend extends Test implements TestExtendI {
private Integer age;
public TestExtend(String name) {
super(name);
}
public TestExtend(String name, Integer age) {
super(name);
this.age = age;
}
@Override
public Integer getAge() {
return age;
}
}
Mixin definizioni
public interface TestMixIn {
@JsonProperty("base-name")
public String getName();
}
public interface TestExtendMixIn {
@JsonProperty("ext-name")
public String getName();
@JsonProperty("ext-age")
public Integer getAge();
}
Se vengono aggiunti entrambi mixins al mapper l'output JSON è:
{
"base-name": "5", // from parent class mixin definition
"ext-age": 50 // from child class mixin defition
}
Con mixin per TestI.class commentato tutto funziona come previsto e l'uscita JSON è (questo è quello che vorrei realizzare):
{
"ext-name": "5", // from child class mixin defition
"ext-age": 50 // from child class mixin defition
}
configurazione Object Mapper
@Provider
@Produces(MediaType.APPLICATION_JSON)
public class JacksonObjectMapper implements ContextResolver<ObjectMapper> {
private ObjectMapper mapper;
public JacksonObjectMapper() {
mapper = new ObjectMapper();
mapper.addMixInAnnotations(TestI.class, TestMixIn.class);
mapper.addMixInAnnotations(TestExtendI.class, TestExtendMixIn.class);
}
public ObjectMapper getContext(Class<?> type) {
return this.mapper;
}
}
REST api per la gestione della richiesta/risposta
@Path("api/test/{id}")
public class TestRestApi {
@GET
@Produces({MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML})
public TestI getTest(@PathParam("id") String id) {
TestI ret = new TestExtend(id, 50);
return ret;
}
}
Soluzione
Come descritto da pgelinas nella prima risposta, la soluzione a questo problema è definire i metodi che devono essere gestiti dal mixin "figlio" di nuovo nell'interfaccia figlio. Per il codice di esempio di cui sopra che significherebbe modifiche all'interfaccia TestExtendI:
public interface TestExtendI extends TestI {
public Integer getAge();
// override the method from the parent interface here
@Override
public String getName();
}
questo risolverà il problema e non aggiungere il codice boilerplate troppo alla soluzione. Inoltre non cambierà i contratti di interfaccia poiché l'interfaccia figlio estende già l'interfaccia genitore.
Grazie, funziona davvero. – user2239050