2011-07-31 9 views
10

tengo una clase que tiene este aspecto:

public class Person { 
    public class Address { 
     private String line1; 
     private String line2; 
     private String zipCode; 
     private String state; 

     // standard public getters and setters for the class here 
    } 

private String name; 
private String address; 

// standard public getters and setters for the class here 

} 

y he aquí cómo Estoy usando a Jackson con eso.

public class JsonTest { 
    public static <T> Object fromJson(String jsonAsString, Class<T> pojoClass) 
throws JsonMappingException, JsonParseException, IOException { 
     return m.readValue(jsonAsString, pojoClass); 
    } 

    public static String toJson(Object pojo, boolean prettyPrint) 
throws JsonMappingException, JsonGenerationException, IOException { 
     StringWriter sw = new StringWriter(); 
     JsonGenerator jg = jf.createJsonGenerator(sw); 
     if (prettyPrint) { 
      jg.useDefaultPrettyPrinter(); 
     } 
     m.writeValue(jg, pojo); 
     return sw.toString(); 
    } 

    public static void main(String[] args) { 
     Person p = new Person(); 
     String json = this.toJson(p, true); // converts ‘p’ to JSON just fine 
     Person personFromJson = this.fromJson(json, Person.class); // throws exception!!! 
    } 
} 

la tercera línea del método principal (donde intento de convertir a JSON objeto Person), lanza esta excepción:

IOException: Can not deserialize Class com.mycompany.models.Person$Address (of type non-static member class) as a Bean 

¿qué estoy haciendo mal?

+2

Parece que no puede serializar dichas clases; consulte http://www.cowtowncoder.com/blog/archives/2010/08/entry_411.html para obtener más información –

+0

@Stas Kurilin - Debe convertir ese comentario en una respuesta, es la correcta. – Perception

+0

@Perception, hecho. Pero espero que smb pueda ayudar a ishaq de una mejor manera. –

Respuesta

8

Dado que las clases internas no tienen un constructor predeterminado de argumento cero (tienen una referencia oculta a la clase externa/principal) Jackson no puede crear una instancia de ellas.

La solución es utilizar static clases internas:

public class Outer { 
    static class Inner { 
     private String foo; 
     public String getFoo() { return foo; } 
    } 
} 

respuesta original:

Hay algunos problemas en la aplicación y parece que no se puede serializar dichas clases, consulte cowtowncoder de detalles.

+0

¡Señor! son un caballero –

3

Correcto, esto solía ser algo que no se puede hacer con las versiones actuales de Jackson (1.8 y anteriores). ¿Pero es absolutamente necesario que la clase interna no sea estática? Si no, solo agrega 'estático' en la declaración de dirección y funcionará bien; El problema es con el puntero "oculto" que las clases internas no estáticas toman vía constructor.

Jackson 1.9 realmente apoyará la deserialización de usos simples de clases internas no estáticas, vea esto Jira entry.

+0

sí, eso es exactamente lo que hice, agregué declaraciones 'estáticas' a la clase interna. no sabía cómo diferían las clases internas no estáticas y estáticas, ahora lo sé. Gracias. –

+0

Ok, me alegro de que haya sido así de fácil. :) – StaxMan

Cuestiones relacionadas