2011-03-30 12 views
24

Quiero convertir una cadena JSON en objeto java, pero la clase de este objeto contiene campos abstractos, que Jackson no puede crear instancias, y no produce el objeto. ¿Cuál es la forma más fácil de decir que de algunas implementación predeterminada de una clase abstracta, comoBiblioteca Jackson JSON: cómo crear una instancia de una clase que contiene campos abstractos

setDefault(AbstractAnimal.class, Cat.class); 

o para decidir acerca de la clase de implementación basado en JSON nombre de atributo, por ejemplo. para JSON objeto:

{ 
    ... 
    cat: {...} 
    ... 
} 

me acaba de Wite:

setImpl("cat", Cat.class); 


Sé que es posible en Jackson insertar la información de clase en el interior JSON, pero yo no quiero complicar el formato JSON I utilizar. Quiero decidir qué clase que se utiliza simplemente mediante el establecimiento de clase de implementación por defecto, o por el nombre del atributo ('gato') - al igual que en la biblioteca xstream, en el que escribe:

xStream.alias("cat", Cat.class); 

¿Hay una manera de hacerlo, especialmente en una línea, ¿o requiere más código?

+0

No existe un 'campo abstracto' en Java. – EJP

+1

lo que quise decir es: 'clase C {Animal animal; } ' y quiero crear una instancia de C, donde Aniaml es abstracto, y quiero poner en este campo un gato, que extiende Animal – Marcin

+0

por lo que no hay problema. No existe una regla para que las variables sean de tipo abstracto. – EJP

Respuesta

36

Existen varias formas; antes de la versión 1.8, forma más sencilla es probablemente hacer:

@JsonDeserialize(as=Cat.class) 
public abstract class AbstractAnimal { ... } 

como de decidir sobre la base de atributos, es mejor hacerlo utilizando @JsonTypeInfo, lo que hace embeddeding automática (cuando la escritura) y el uso de información de tipo.

Existen varios tipos de información de tipo (nombre de clase, nombre de tipo lógico), así como mecanismos de inclusión (como-propiedad-incluida, como-envoltorio-matriz, como-envoltorio-objeto). Esta página: https://github.com/FasterXML/jackson-docs/wiki/JacksonPolymorphicDeserialization explica algunos de los conceptos.

+0

¡Gracias por la respuesta! @JsonDeserialize es lo que será ideal para mi problema, ya que no requiere incrustar ningún tipo de información en el JSON. Sin embargo, no puedo usar esto, ya que no puedo modificar las clases que quiero instanciar, ya que son parte de otros proyectos, y cambiar este código podría romper otro código. – Marcin

+4

Las anotaciones también son bastante inflexibles, ya que no puedo decidir dinámicamente qué implementación utilizo. – Marcin

+1

Wrt modificando clases, esto es para lo que son las anotaciones mixtas de Jackson. Pero correcto, esta anotación solo se usa para casos en los que solo hay un tipo de implementación. Jackson 1.8 tendrá funcionalidad para permitir el tipo abstracto abstracto -> mapeo tipo impl, por lo que vale. – StaxMan

2

Una respuesta de pleno derecho con un ejemplo muy claro se puede encontrar aquí: https://stackoverflow.com/a/30386694/584947

Jackson refiere a esto como polimórfica Deserialización.

Definitivamente me ayudó con mi problema. Tenía una clase abstracta que estaba guardando en una base de datos y necesitaba descomponerla en una instancia concreta de una clase (comprensiblemente).

Le mostrará cómo anotar correctamente la clase abstracta principal y cómo enseñarle a jackson cómo elegir entre los candidatos de la subclase disponibles en el tiempo de ejecución al desasociar.

Cuestiones relacionadas