it-swarm.com.de

Jackson mit JSON: Nicht erkanntes Feld, nicht als ignorierbar markiert

Ich muss eine bestimmte JSON-Zeichenfolge in ein Java -Objekt konvertieren. Ich benutze Jackson für das JSON-Handling. Ich habe keine Kontrolle über die Eingabe von JSON (ich habe von einem Web-Service gelesen). Dies ist meine Eingabe JSON:

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

Hier ist ein vereinfachter Anwendungsfall:

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);
}

Meine Entitätsklasse ist:

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

Meine Wrapper-Klasse ist im Grunde ein Containerobjekt, um meine Schülerliste abzurufen:

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

Ich erhalte immer wieder diesen Fehler und "wrapper" gibt null zurück. Ich bin nicht sicher, was fehlt. Kann mir bitte jemand helfen?

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: 
    Unrecognized field "wrapper" (Class Wrapper), not marked as ignorable
 at [Source: [email protected]; line: 1, column: 13] 
    (through reference chain: Wrapper["wrapper"])
 at org.codehaus.jackson.map.exc.UnrecognizedPropertyException
    .from(UnrecognizedPropertyException.Java:53)
576
jshree

Sie können Jacksons Annotation auf Klassenebene verwenden:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties

@JsonIgnoreProperties
class { ... }

Jede Eigenschaft, die Sie nicht in Ihrem POJO definiert haben, wird ignoriert. Sehr nützlich, wenn Sie nur nach einigen Eigenschaften in JSON suchen und nicht das gesamte Mapping schreiben möchten. Mehr Infos unter Jacksons Website . Wenn Sie eine nicht deklarierte Eigenschaft ignorieren möchten, sollten Sie Folgendes schreiben:

@JsonIgnoreProperties(ignoreUnknown = true)
883
Ariel Kogan

Sie können verwenden

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

Alle nicht deklarierten Eigenschaften werden ignoriert.

412

Die erste Antwort ist fast richtig, aber es muss die Getter-Methode geändert werden, NICHT das Feld - das Feld ist privat (und wird nicht automatisch erkannt). Außerdem haben Getter Vorrang vor Feldern, wenn beide sichtbar sind. (Es gibt auch Möglichkeiten, private Felder sichtbar zu machen, aber wenn Sie Getter haben möchten, gibt es nicht viel Sinn.)

Daher sollte getter entweder getWrapper() heißen oder mit folgenden Anmerkungen versehen sein:

@JsonProperty("wrapper")

Wenn Sie den Namen der Getter-Methode bevorzugen.

120
StaxMan

mit Jackson 2.6.0 funktionierte das für mich:

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

und mit Einstellung:

@JsonIgnoreProperties(ignoreUnknown = true)
78
Scott

es kann auf zwei Arten erreicht werden:

  1. Markieren Sie das POJO, um unbekannte Eigenschaften zu ignorieren

    @JsonIgnoreProperties(ignoreUnknown = true)
    
  2. Konfigurieren Sie den ObjectMapper, der das POJO/json serialisiert/deserialisiert, wie folgt:

    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) 
    
49
Anamika

Das hat bei mir einfach perfekt funktioniert

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

@JsonIgnoreProperties(ignoreUnknown = true) Annotation nicht.

39
Felix Kimutua

Dies funktioniert besser als Alle Bitte beziehen Sie sich auf diese Eigenschaft.

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);
35
Karan

Wenn Sie Jackson 2.0 verwenden

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

Gemäß doc können Sie ausgewählte Felder oder alle unbekannten Felder ignorieren:

 // to prevent specified fields from being serialized or deserialized
 // (i.e. 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)
18
tomrozb

Es hat bei mir mit folgendem Code geklappt:

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

Jackson beschwert sich, weil es in Ihrem Klassen-Wrapper kein Feld mit dem Namen "wrapper" finden kann. Dies geschieht, weil Ihr JSON-Objekt eine Eigenschaft namens "wrapper" hat.

Ich denke, die Lösung besteht darin, das Feld Ihrer Wrapper-Klasse in "Wrapper" anstelle von "Students" umzubenennen.

12
Jim Ferrans

Ich habe die folgende Methode ausprobiert und sie funktioniert für das Lesen im JSON-Format mit Jackson. Verwenden Sie die bereits vorgeschlagene Lösung von: Kommentieren von Gettern mit @JsonProperty("wrapper")

Ihre Wrapper-Klasse

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

Mein Vorschlag der Wrapper-Klasse

public Class Wrapper{ 

  private StudentHelper students; 

  //getters & setters here 
  // Annotate getter
  @JsonProperty("wrapper")
  StudentHelper getStudents() {
    return students;
  }  
} 


public class StudentHelper {

  @JsonProperty("Student")
  public List<Student> students; 

  //CTOR, getters and setters
  //NOTE: If students is private annotate getter with the annotation @JsonProperty("Student")
}

Dies würde jedoch die Ausgabe des Formats ergeben:

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

Weitere Informationen finden Sie auch unter https://github.com/FasterXML/jackson-annotations

Hoffe das hilft

12
mytwocentsads

Diese Lösung ist generisch, wenn Sie JSON-Streams lesen und nur einige Felder abrufen müssen, während Felder, die in Ihren Domänenklassen nicht korrekt zugeordnet sind, ignoriert werden können:

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

Eine detaillierte Lösung wäre, ein Tool wie jsonschema2pojo zu verwenden, um die erforderlichen Domänenklassen wie Student automatisch aus dem Schema der json-Antwort zu generieren. Letzteres können Sie mit jedem Online-Konverter von JSON zu Schema ausführen.

10

Kommentieren Sie die Feldstudenten wie folgt, da die Namen der json-Eigenschaft und der Java-Eigenschaft nicht übereinstimmen

public Class Wrapper {
    @JsonProperty("wrapper")
    private List<Student> students;
    //getters & setters here
}
9
ajith r

Wie noch niemand erwähnt hat, dachte ich würde ...

Problem ist, dass Ihre Eigenschaft in Ihrem JSON "wrapper" heißt und Ihre Eigenschaft in Wrapper.class "students" heißt.

Also entweder...

  1. Korrigieren Sie den Namen der Eigenschaft in der Klasse oder in JSON.
  2. Kommentieren Sie Ihre Eigenschaftsvariable gemäß dem Kommentar von StaxMan.
  3. Kommentiere den Setter (falls du einen hast)
8
TedTrippin

Entweder ändern

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

zu

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

---- oder ----

Ändern Sie Ihre JSON-Zeichenfolge in

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

Deine Eingabe

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

gibt an, dass es sich um ein Objekt mit einem Feld namens "wrapper" handelt, das eine Sammlung von Schülern ist. Also meine Empfehlung wäre,

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

wobei Wrapper definiert ist als

class Wrapper {
    List<Student> wrapper;
}
5
Ran0990BK

Was für mich funktionierte, war, das Eigentum öffentlich zu machen. Es hat das Problem für mich gelöst.

4
Rohitesh

Die neue Firebase Android führte einige große Änderungen ein; unter der Kopie des Dokuments:

[ https://firebase.google.com/support/guides/firebase-Android]:

Aktualisieren Sie Ihre Java Modellobjekte

Wie beim 2.x SDK konvertiert Firebase Database automatisch Java Objekte, die Sie an DatabaseReference.setValue() übergeben, in JSON und kann JSON mit DataSnapshot.getValue() in Java Objekte einlesen.

Wenn Sie im neuen SDK JSON in ein Java - Objekt mit DataSnapshot.getValue() einlesen, werden unbekannte Eigenschaften in JSON jetzt standardmäßig ignoriert, sodass Sie @JsonIgnoreExtraProperties(ignoreUnknown=true) nicht mehr benötigen.

Um Felder/Getter beim Schreiben eines Java - Objekts in JSON auszuschließen, heißt die Annotation jetzt @Exclude anstelle von @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)

Wenn in Ihrem JSON eine zusätzliche Eigenschaft vorhanden ist, die sich nicht in Ihrer Klasse Java befindet, wird diese Warnung in den Protokolldateien angezeigt:

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

Sie können diese Warnung beseitigen, indem Sie eine @IgnoreExtraProperties -Anmerkung in Ihre Klasse einfügen. Wenn Sie möchten, dass sich die Firebase-Datenbank wie im 2.x-SDK verhält und eine Ausnahme auslöst, wenn unbekannte Eigenschaften vorliegen, können Sie Ihrer Klasse eine Anmerkung @ThrowOnExtraProperties hinzufügen.

4
ThierryC

Das hat bei mir perfekt funktioniert

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
4
Niamath

Ich habe dieses Problem behoben, indem ich einfach die Signaturen meiner Setter- und Getter-Methoden meiner POJO-Klasse geändert habe. Ich musste nur die Methode getObject so ändern, dass sie dem entspricht, was der Mapper suchte. In meinem Fall hatte ich ursprünglich ein getImageUrl, aber die JSON-Daten hatten image_url, was den Mapper auslöste. Ich habe sowohl Setter als auch Getter auf getImage_url und setImage_url geändert.

Hoffe das hilft.

4
superuserdo

Für meinen Teil die einzige Zeile

@JsonIgnoreProperties(ignoreUnknown = true)

hat auch nicht funktioniert.

Einfach hinzufügen

@JsonInclude(Include.NON_EMPTY)

Jackson 2.4.0

4
jodu

setze public deine Klassenfelder nicht private.

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

Das POJO sollte definiert sein als

Antwortklasse

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

Wrapper-Klasse

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

und Mapper, um den Wert zu lesen

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

Eine andere Möglichkeit ist diese Eigenschaft in der Datei application.properties spring.jackson.deserialization.fail-on-unknown-properties=false, für die in Ihrer Anwendung keine weiteren Codeänderungen erforderlich sind. Und wenn Sie glauben, dass der Vertrag stabil ist, können Sie diese Eigenschaft entfernen oder als wahr markieren.

3
krmanish007

Dies mag nicht das gleiche Problem sein, das das OP hatte, aber falls jemand mit dem gleichen Fehler wie ich hier ankam, wird dies ihm helfen, sein Problem zu lösen. Ich habe den gleichen Fehler wie beim OP erhalten, als ich einen ObjectMapper aus einer anderen Abhängigkeit als die JsonProperty-Annotation verwendet habe.

Das funktioniert:

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonProperty;

Funktioniert nicht:

import org.codehaus.jackson.map.ObjectMapper; //org.codehaus.jackson:jackson-mapper-asl:1.8.8
import com.fasterxml.jackson.annotation.JsonProperty; //com.fasterxml.jackson.core:jackson-databind:2.2.3
2
cwa

Google hat mich hierher gebracht und ich war überrascht, die Antworten zu sehen ... alle vorgeschlagenen mgeht ​​den Fehler (der immer 4 Falten später in der Entwicklung zurückbeißt), anstatt ihn zu lösen, bis dieser Herr durch den Glauben an SO wiederhergestellt!

objectMapper.readValue(responseBody, TargetClass.class)

wird verwendet, um einen json-String in ein Klassenobjekt zu konvertieren. Was fehlt, ist, dass das TargetClass öffentliche getter/setters haben sollte. Das Gleiche fehlt auch in OPs Fragenschnipsel! :)

via lombok deine klasse wie unten sollte funktionieren !!

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

Dies kann eine sehr späte Antwort sein, aber nur das Ändern des POJO in dies sollte den im Problem angegebenen json-String lösen (da der Eingabe-String nicht in Ihrer Kontrolle ist, wie Sie sagten):

public class Wrapper {
    private List<Student> wrapper;
    //getters & setters here
}
2
Sayantan

In meinem Fall war es einfach: Das JSON-Objekt des REST-Service wurde aktualisiert (eine Eigenschaft wurde hinzugefügt), das JSON-Objekt des REST-Clients jedoch nicht. Sobald ich ein JSON-Client-Objekt aktualisiert habe, ist die Ausnahme "Nicht erkanntes Feld ..." verschwunden.

1
blue-bird

Ändern Sie die Wrapper-Klasse in

public Class Wrapper {

          @JsonProperty("wrapper")  // add this line
          private List<Student> students;
}

Damit wird das students -Feld als wrapper -Schlüssel des json-Objekts erkannt.

Ich persönlich bevorzuge auch die Verwendung von Lombok Annotations für Getter und Setter als

@Getter
@Setter
public Class Wrapper {

          @JsonProperty("wrapper")  // add this line
          private List<Student> students;
}

Da ich den obigen Code nicht zusammen mit Lombok und @JsonProperty getestet habe, empfehle ich Ihnen, der Wrapper-Klasse den folgenden Code hinzuzufügen und Lomboks Standard-Getter und -Setter zu überschreiben.

public List<Student> getWrapper(){
     return students;
}

public void setWrapper(List<Student> students){
     this.students = students;
}

Überprüfen Sie auch this out, um Listen mit Jackson zu deserialisieren.

0
devilsbane

In meinem Fall ist der Fehler auf folgenden Grund zurückzuführen

  • Am Anfang hat es gut funktioniert, dann habe ich eine Variable umbenannt, die Änderungen im Code vorgenommen und es gab mir diesen Fehler.

  • Dann habe ich auch Jacksons unwissendes Eigentum angewendet, aber es hat nicht funktioniert.

  • Nachdem ich meine Get- und Setter-Methoden nach dem Namen meiner Variablen neu definiert hatte, wurde dieser Fehler behoben

Stellen Sie also sicher, dass Sie auch Getter und Setter neu definieren.

0
Vikram Saini

import com.fasterxml.jackson.annotation.JsonIgnoreProperties;

@JsonIgnoreProperties

0
Gank

Sie sollten nur das Listenfeld von "students" in "wrapper" ändern, nur die json-Datei, und der Mapper sucht danach.

0
Troy

Ihre JSON-Zeichenfolge stimmt nicht mit der zugeordneten Klasse überein. Ändern Sie die Eingabezeichenfolge

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

Oder ändern Sie Ihre zugeordnete Klasse

public class Wrapper {
    private List<Student> wrapper;
    //getters & setters here
}
0
xLime