defaulttyping - Jackson JsonTypeInfo.As.EXTERNAL_PROPERTY no funciona como se esperaba
jackson inheritance (1)
Estoy utilizando a Jackson para analizar JSON sobre el que no tengo control. El JSON se ve así:
{
"status":"0"
"type":"type1"
"info": {
// additional fields
}
}
Mi clase se ve asi
public class Response {
private String status;
private String type;
private Info info
}
La subclase de información que uso depende de la propiedad type, por lo que mi asignación para información es
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
@JsonSubTypes(value = {
@JsonSubTypes.Type(value = Type1Info.class, name = "type1"),
@JsonSubTypes.Type(value = Type2Info.class, name = "type2") })
public abstract class Info {
// some fields
}
Por lo que puedo decir, esta es la forma correcta de usar información de tipo cuando el elemento distintivo se encuentra en el mismo nivel que el elemento que se tiene que moldear. Pero esto no funciona, siempre me sale el mismo error:
com.fasterxml.jackson.databind.JsonMappingException: token inesperado (END_OBJECT), FIELD_NAME esperado: propiedad ''tipo'' faltante que debe contener el ID de tipo
Si cambio EXTERNAL_PROPERTY a PROPIEDAD, sigo recibiendo el mismo error. ¿Mi comprensión de EXTERNAL_PROPERTY es incorrecta?
Desde Javadoc:
Mecanismo de inclusión similar a PROPIEDAD, excepto que la propiedad se incluye en un nivel superior en la jerarquía, es decir, como propiedad de hermano en el mismo nivel que el objeto JSON para escribir. Tenga en cuenta que esta opción solo se puede utilizar para propiedades , no para tipos (clases). Tratar de usarlo para las clases resultará en una estrategia de inclusión de PROPIEDAD básica en su lugar.
Notado que can only be used for properties
está en negrita. Fuente: JsonTypeInfo.As.EXTERNAL_PROPERTY .
Por lo tanto, debe mover todas las anotaciones de la clase de Info
a la info
propiedad o setInfo
método setInfo
en la clase de Response
.
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.EXTERNAL_PROPERTY, property = "type")
@JsonSubTypes(value = { @JsonSubTypes.Type(value = Type1Info.class, name = "type1"),
@JsonSubTypes.Type(value = Type2Info.class, name = "type2") })
public void setInfo(Info info) {
this.info = info;
}
Para mí, también debe eliminar la propiedad de type
de la clase Response
. Se generará dinámicamente durante el proceso de serialización. En la deserialización no es necesario porque Jackson se preocupa por los tipos. Tu clase podría verse así:
class Response {
private String status;
private Info info;
//getters, setters
}
Véase también esta pregunta: JSON nest class data binding .