Jackson con JSON: campo no reconocido, no marcado como ignorable

Necesito convertir una cierta cadena JSON en un objeto Java. Estoy usando Jackson para el manejo de JSON. No tengo control sobre la entrada JSON (leo de un servicio web). Esta es mi entrada JSON:

{"wrapper":[{"id":"13","name":"Fred"}]} 

Aquí hay un caso de uso simplificado:

 private void tryReading() { String jsonStr = "{\"wrapper\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}"; ObjectMapper mapper = new ObjectMapper(); Wrapper wrapper = null; try { wrapper = mapper.readValue(jsonStr , Wrapper.class); } catch (Exception e) { e.printStackTrace(); } System.out.println("wrapper = " + wrapper); } 

Mi clase de entidad es:

 public Class Student { private String name; private String id; //getters & setters for name & id here } 

Mi clase Wrapper es básicamente un objeto contenedor para obtener mi lista de estudiantes:

 public Class Wrapper { private List students; //getters & setters here } 

Sigo recibiendo este error y “envoltorio” devuelve null . No estoy seguro de lo que falta. ¿Puede alguien ayudar, por favor?

 org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "wrapper" (Class Wrapper), not marked as ignorable at [Source: java.io.StringReader@1198891; line: 1, column: 13] (through reference chain: Wrapper["wrapper"]) at org.codehaus.jackson.map.exc.UnrecognizedPropertyException .from(UnrecognizedPropertyException.java:53) 

Puedes usar la anotación de nivel de clase de Jackson:

 @JsonIgnoreProperties 

Ignorará cada propiedad que no haya definido en su POJO. Muy útil cuando solo busca un par de propiedades en el JSON y no desea escribir todo el mapeo. Más información en el sitio web de Jackson . Si desea ignorar cualquier propiedad no declarada, debe escribir:

 @JsonIgnoreProperties(ignoreUnknown = true) 

Puedes usar

 ObjectMapper objectMapper = getObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

Ignorará todas las propiedades que no están declaradas.

La primera respuesta es casi correcta, pero lo que se necesita es cambiar el método getter, NO campo – campo es privado (y no se detecta automáticamente); Además, los getters tienen prioridad sobre los campos si ambos son visibles (también hay formas de hacer que los campos privados sean visibles, pero si quieres tener getter no hay mucho más)

Así getter debe ser llamado getWrapper() , o anotado con:

 @JsonProperty("wrapper") 

Si prefiere el nombre del método getter como es.

usando Jackson 2.6.0, esto funcionó para mí:

 private static final ObjectMapper objectMapper = new ObjectMapper() .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

y con el ajuste:

 @JsonIgnoreProperties(ignoreUnknown = true) 

Esto funcionó perfectamente para mí

 ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure( DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

@JsonIgnoreProperties(ignoreUnknown = true) anotación no.

Esto funciona mejor que Todos, por favor refiérase a esta propiedad.

 import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; ObjectMapper objectMapper = new ObjectMapper(); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); projectVO = objectMapper.readValue(yourjsonstring, Test.class); 

se puede lograr de 2 maneras:

  1. Marque el POJO para ignorar las propiedades desconocidas

     @JsonIgnoreProperties(ignoreUnknown = true) 
  2. Configure ObjectMapper que serialice / De-serialice el POJO / json de la siguiente manera:

     ObjectMapper mapper =new ObjectMapper(); // for Jackson version 1.X mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); // for Jackson version 2.X mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false) 

Si está usando Jackson 2.0

 ObjectMapper mapper = new ObjectMapper(); mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES); 

De acuerdo con el documento , puede ignorar los campos seleccionados o todos los campos conocidos:

  // to prevent specified fields from being serialized or deserialized // (ie not include in JSON output; or being set even if they were included) @JsonIgnoreProperties({ "internalId", "secretKey" }) // To ignore any unknown properties in JSON input without exception: @JsonIgnoreProperties(ignoreUnknown=true) 

Me funcionó con el siguiente código:

 ObjectMapper mapper =new ObjectMapper(); mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

Jackson se queja porque no puede encontrar un campo en su clase Wrapper que se llama “envoltorio”. Está haciendo esto porque su objeto JSON tiene una propiedad llamada “envoltorio”.

Creo que la solución es cambiar el nombre del campo de la clase Wrapper a “contenedor” en lugar de “estudiantes”.

He intentado el siguiente método y funciona para tal lectura de formato JSON con Jackson. Use la solución ya sugerida de: anotación getter con @JsonProperty("wrapper")

Su clase de envoltura

 public Class Wrapper{ private List students; //getters & setters here } 

Mi sugerencia de clase contenedora

 public Class Wrapper{ private StudentHelper students; //getters & setters here // Annotate getter @JsonProperty("wrapper") StudentHelper getStudents() { return students; } } public class StudentHelper { @JsonProperty("Student") public List students; //CTOR, getters and setters //NOTE: If students is private annotate getter with the annotation @JsonProperty("Student") } 

Sin embargo, esto le daría el resultado del formato:

 {"wrapper":{"student":[{"id":13,"name":Fred}]}} 

También para más información, consulte https://github.com/FasterXML/jackson-annotations

Espero que esto ayude

Esta solución es genérica al leer flujos json y necesita obtener solo algunos campos mientras que los campos no asignados correctamente en sus clases de dominio pueden ignorarse:

 import org.codehaus.jackson.annotate.JsonIgnoreProperties; @JsonIgnoreProperties(ignoreUnknown = true) 

Una solución detallada sería usar una herramienta como jsonschema2pojo para autogenerar las clases de dominio requeridas, como Student, del esquema de la respuesta json. Puede hacer esto último mediante cualquier conversor en línea de esquema a esquema.

Como nadie más ha mencionado, pensé que …

El problema es que su propiedad en su JSON se llama “envoltura” y su propiedad en Wrapper.class se llama “estudiantes”.

Entonces o …

  1. Corrija el nombre de la propiedad en la clase o JSON.
  2. Anota tu variable de propiedad según el comentario de StaxMan.
  3. Anota al colocador (si tienes uno)

Anote a los estudiantes de campo de la siguiente manera ya que no coinciden los nombres de la propiedad json y la propiedad java

 public Class Wrapper { @JsonProperty("wrapper") private List students; //getters & setters here } 

Tu aportación

 {"wrapper":[{"id":"13","name":"Fred"}]} 

indica que es un Objeto, con un campo llamado “envoltorio”, que es una Colección de Estudiantes. Entonces mi recomendación sería

 Wrapper = mapper.readValue(jsonStr , Wrapper.class); 

donde Wrapper se define como

 class Wrapper { List wrapper; } 

Lo que funcionó para mí fue hacer pública la propiedad. Me solucionó el problema.

O bien cambio

 public Class Wrapper { private List students; //getters & setters here } 

a

 public Class Wrapper { private List wrapper; //getters & setters here } 

—- o —-

Cambie su cadena JSON a

 {"students":[{"id":"13","name":"Fred"}]} 

Por mi parte, la única línea

@JsonIgnoreProperties(ignoreUnknown = true)

tampoco funcionó

Solo agrega

 @JsonInclude(Include.NON_EMPTY) 

Jackson 2.4.0

Esto funcionó perfectamente para mí

 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); 

Solucioné este problema simplemente cambiando las firmas de mis métodos setter y getter de mi clase POJO. Todo lo que tuve que hacer fue cambiar el método getObject para que coincida con lo que el mapeador estaba buscando. En mi caso, tenía un getImageUrl originalmente, pero los datos de JSON tenían image_url, que arrojaba el asignador. Cambié tanto mi setter como getters para getImage_url y setImage_url .

Espero que esto ayude.

El POJO debe definirse como

Clase de respuesta

 public class Response { private List wrappers; // getter and setter } 

Clase de envoltura

 public class Wrapper { private String id; private String name; // getters and setters } 

y mapeador para leer valor

 Response response = mapper.readValue(jsonStr , Response.class); 

El nuevo Firebase Android introdujo algunos cambios enormes; debajo de la copia del documento:

[ https://firebase.google.com/support/guides/firebase-android%5D :

Actualice sus objetos del modelo de Java

Al igual que con el SDK 2.x, la base de datos de Firebase convertirá automáticamente los objetos Java que pase a DatabaseReference.setValue() en JSON y podrá leer JSON en objetos Java utilizando DataSnapshot.getValue() .

En el nuevo SDK, al leer JSON en un objeto Java con DataSnapshot.getValue() , las propiedades desconocidas en el JSON ahora se ignoran por defecto, por lo que ya no necesita @JsonIgnoreExtraProperties(ignoreUnknown=true) .

Para excluir campos / getters al escribir un objeto Java en JSON, la anotación ahora se llama @Exclude lugar de @JsonIgnore .

 BEFORE @JsonIgnoreExtraProperties(ignoreUnknown=true) public class ChatMessage { public String name; public String message; @JsonIgnore public String ignoreThisField; } dataSnapshot.getValue(ChatMessage.class) 

 AFTER public class ChatMessage { public String name; public String message; @Exclude public String ignoreThisField; } dataSnapshot.getValue(ChatMessage.class) 

Si hay una propiedad adicional en su JSON que no está en su clase Java, verá esta advertencia en los archivos de registro:

 W/ClassMapper: No setter/field for ignoreThisProperty found on class com.firebase.migrationguide.ChatMessage 

Puede deshacerse de esta advertencia colocando una anotación @IgnoreExtraProperties en su clase. Si desea que la base de datos de Firebase se comporte como lo hizo en el SDK 2.x y genere una excepción si hay propiedades desconocidas, puede colocar una anotación @ThrowOnExtraProperties en su clase.

establecer públicos sus campos de clase no privados .

 public Class Student { public String name; public String id; //getters & setters for name & id here } 

En mi caso, fue simple: el objeto JSON REST-service se actualizó (se agregó una propiedad), pero el objeto JSON REST-Client no. Tan pronto como actualizo el objeto del cliente JSON, la excepción ‘Campo no reconocido …’ ha desaparecido.

Esta puede ser una respuesta muy tardía, pero solo cambiar el POJO a esto debería resolver la cadena json proporcionada en el problema (ya que la cadena de entrada no está bajo su control como dijiste):

 public class Wrapper { private List wrapper; //getters & setters here } 

Google me trajo aquí y me sorprendió ver las respuestas … todas sugeridas sobrepasando el error ( que siempre se traduce 4 veces más adelante en el desarrollo ) en lugar de resolverlo hasta que este caballero restaurado por la fe en SO!

 objectMapper.readValue(responseBody, TargetClass.class) 

se usa para convertir un json String a un objeto de clase, lo que falta es que TargetClass debe tener get / set públicos. ¡Igual falta en el fragmento de pregunta de OP también! 🙂

¡A través de lombok tu clase como la siguiente debería funcionar!

 @Data @Builder public class TargetClass { private String a; } 

Debería simplemente cambiar el campo de la Lista de “estudiantes” a “envoltorio” simplemente el archivo json y el asignador lo buscará.

Su cadena json no está en línea con la clase mapeada. Cambiar la cadena de entrada

 String jsonStr = "{\"students\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}"; 

O cambie su clase asignada

 public class Wrapper { private List wrapper; //getters & setters here } 

En mi caso, el error vino debido al siguiente motivo

  • Inicialmente funcionaba bien, luego cambié el nombre de una variable, hice los cambios en el código y me dio este error.

  • Luego apliqué propiedad ignorante jackson también pero no funcionó.

  • Finalmente después de volver a definir mis métodos getters y setters de acuerdo al nombre de mi variable, este error fue resuelto

Así que asegúrese de volver a marcar los get y setters también.