Jackson met JSON: niet-herkend veld, niet gemarkeerd als negeerbaar

Ik moet een bepaalde JSON-string converteren naar een Java-object. Ik gebruik Jackson voor JSON-afhandeling. Ik heb geen controle over de invoer-JSON (ik lees van een webservice). Dit is mijn input-JSON:

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

Hier is een vereenvoudigd gebruiksvoorbeeld:

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

Mijn entiteitsklasse is:

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

Mijn Wrapper-klas is in feite een containerobject om mijn lijst met studenten op te halen:

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

Ik krijg steeds deze foutmelding en “wrapper” retourneert null. Ik weet niet zeker wat er ontbreekt. Kan iemand me alsjeblieft helpen?

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)

Antwoord 1, autoriteit 100%

Je kunt de annotatie op klasniveau van Jackson gebruiken:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties
class { ... }

Het negeert elke eigenschap die je niet hebt gedefinieerd in je POJO. Erg handig wanneer u slechts een paar eigenschappen in de JSON zoekt en niet de hele toewijzing wilt schrijven. Meer info op Jacksons website. Als u een niet-aangegeven eigenschap wilt negeren, moet u schrijven:

@JsonIgnoreProperties(ignoreUnknown = true)

Antwoord 2, autoriteit 52%

U kunt gebruiken

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

Het negeert alle eigenschappen die niet zijn gedeclareerd.


Antwoord 3, autoriteit 12%

Het eerste antwoord is bijna correct, maar wat nodig is, is om de gettermethode te veranderen, NIET het veld — het veld is privé (en niet automatisch gedetecteerd); verder hebben getters voorrang op velden als beide zichtbaar zijn. (Er zijn ook manieren om privévelden zichtbaar te maken, maar als je getter wilt hebben, heeft het niet veel zin)

Dus getter moet ofwel getWrapper()worden genoemd, of geannoteerd worden met:

@JsonProperty("wrapper")

Als u de voorkeur geeft aan de naam van de gettermethode zoals deze is.


Antwoord 4, autoriteit 9%

met Jackson 2.6.0 werkte dit voor mij:

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

en met instelling:

@JsonIgnoreProperties(ignoreUnknown = true)

Antwoord 5, autoriteit 6%

het kan op 2 manieren worden bereikt:

  1. Markeer de POJO om onbekende eigenschappen te negeren

    @JsonIgnoreProperties(ignoreUnknown = true)
    
  2. Configureer ObjectMapper die de POJO/json serialiseert/de-serialiseert zoals hieronder:

    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) 
    

Antwoord 6, autoriteit 4%

Het toevoegen van setters en getters loste het probleem op, ik voelde dat het eigenlijke probleem was hoe het op te lossen, maar niet hoe de fout te onderdrukken/negeren.
Ik krijg de foutmelding “Onbekend veld.. niet gemarkeerd als negeerbaar..

Hoewel ik de onderstaande annotatie bovenop de klasse gebruik, kon het het json-object niet ontleden en me de invoer geven

@JsonIgnoreProperties(ignoreUnknown = true)

Toen realiseerde ik me dat ik geen setters en getters had toegevoegd, na het toevoegen van setters en getters aan de “Wrapper” en aan de “Student” werkte het als een tierelier.


Antwoord 7, autoriteit 4%

Dit werkte gewoon perfect voor mij

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

@JsonIgnoreProperties(ignoreUnknown = true)annotatie niet.


Antwoord 8, autoriteit 4%

Dit werkt beter dan Alles, raadpleeg deze eigenschap.

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

Antwoord 9, autoriteit 3%

Als je Jackson 2.0 gebruikt

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

Antwoord 10, autoriteit 2%

Volgens de dockan geselecteerde velden of alle onbekende velden negeren:

// 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)

Antwoord 11, autoriteit 2%

Het werkte voor mij met de volgende code:

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

Antwoord 12

Ik heb de onderstaande methode geprobeerd en het werkt voor het lezen van een dergelijk JSON-formaat met Jackson.
Gebruik de reeds voorgestelde oplossing van: annoteren van getter met @JsonProperty("wrapper")

Uw wrapper-klasse

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

Mijn suggestie voor 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")
}

Dit geeft u echter de uitvoer van het formaat:

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

Voor meer informatie, zie ook https://github.com/FasterXML/jackson-annotations


Antwoord 13

Jackson klaagt omdat het geen veld in je klasse Wrapper kan vinden dat “wrapper” heet. Het doet dit omdat je JSON-object een eigenschap heeft met de naam “wrapper”.

Ik denk dat de oplossing is om het veld van je Wrapper-klasse te hernoemen naar “wrapper” in plaats van “studenten”.


Antwoord 14

Deze oplossing is generiek bij het lezen van json-streams en hoeft slechts enkele velden te krijgen, terwijl velden die niet correct zijn toegewezen in uw domeinklassen kunnen worden genegeerd:

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

Een gedetailleerde oplossing zou zijn om een ​​tool zoals jsonschema2pojo te gebruiken om de vereiste domeinklassen, zoals Student, automatisch te genereren uit het schema van het json-antwoord. Je kunt het laatste doen met elke online json naar schema-converter.


Antwoord 15

Als u @JsonIgnorePropertieswilt toepassen op alle klassen in uw toepassing, kunt u het beste het standaard jackson-object Spring boot overschrijven.

Definieer in het configuratiebestand van uw toepassing een bean om op deze manier een Jackson Object Mapper te maken.

@Bean
    public ObjectMapper getObjectMapper() {
        ObjectMapper mapper = new ObjectMapper();
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        return mapper;
    }

Je hoeft nu niet elke klasse te markeren en negeert alle onbekende eigenschappen.


Antwoord 16

Annoteer de veldstudenten zoals hieronder, aangezien de namen van de json-eigenschap en de java-eigenschap niet overeenkomen

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

Antwoord 17

Het probleem is dat uw eigendom in uw JSON “wrapper” wordt genoemd en uw eigendom in Wrapper.class “studenten”.

Dus of…

  1. Corrigeer de naam van de eigenschap in de klasse of JSON.
  2. Annoteer uw eigenschapsvariabele volgens de opmerking van StaxMan.
  3. Annoteer de setter (als je die hebt)

Antwoord 18

Op de een of andere manier heeft na 45 berichten en 10 jaar niemand het juiste antwoord voor mijn geval gepost.

@Data //Lombok
public class MyClass {
    private int foo;
    private int bar;
    @JsonIgnore
    public int getFoobar() {
      return foo + bar;
    }
}

In mijn geval hebben we een methode genaamd getFoobar(), maar geen eigenschap foobar(omdat deze wordt berekend op basis van andere eigenschappen). @JsonIgnorePropertiesop de klas werkt niet.

De oplossing is om de methode te annoteren met @JsonIgnore


Antwoord 19

Ofwel wijzigen

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

naar

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

—- of —-

Wijzig uw JSON-tekenreeks in

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

Antwoord 20

Wat voor mij werkte, was om het pand openbaar te maken.


Antwoord 21

Wat mij betreft, de enige regel

@JsonIgnoreProperties(ignoreUnknown = true)

werkte ook niet.

Gewoon toevoegen

@JsonInclude(Include.NON_EMPTY)

Jackson 2.4.0


Antwoord 22

Uw input

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

geeft aan dat het een object is, met een veld met de naam “wrapper”, wat een verzameling studenten is. Dus mijn aanbeveling zou zijn:

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

waar Wrapperis gedefinieerd als

class Wrapper {
    List<Student> wrapper;
}

Antwoord 23

De nieuwe Firebase Android introduceerde een aantal enorme veranderingen; onder de kopie van het document:

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

Update uw Java-modelobjecten

Net als bij de 2.x SDK converteert Firebase Database automatisch Java-objecten die u doorgeeft aan DatabaseReference.setValue()naar JSON en kan JSON in Java-objecten inlezen met DataSnapshot.getValue().

In de nieuwe SDK worden bij het inlezen van JSON in een Java-object met DataSnapshot.getValue()onbekende eigenschappen in de JSON nu standaard genegeerd, zodat u @JsonIgnoreExtraProperties(ignoreUnknown=true).

Om velden/getters uit te sluiten bij het schrijven van een Java-object naar JSON, wordt de annotatie nu @Excludegenoemd in plaats van @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)

Als er een extra eigenschap in uw JSON is die niet in uw Java-klasse zit, ziet u deze waarschuwing in de logbestanden:

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

Je kunt deze waarschuwing verwijderen door een @IgnoreExtraPropertiesannotatie in je klas te plaatsen. Als u wilt dat Firebase Database zich gedraagt ​​zoals in de 2.x SDK en een uitzondering genereert als er onbekende eigenschappen zijn, kunt u een @ThrowOnExtraProperties-annotatie in uw klasse plaatsen.


Antwoord 24

stel uw klasvelden openbaarin en niet privé.

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

Antwoord 25

Een andere mogelijkheid is deze eigenschap in de application.properties
spring.jackson.deserialization.fail-on-unknown-properties=false, waarvoor geen andere codewijziging in uw toepassing nodig is. En als u denkt dat het contract stabiel is, kunt u deze eigenschap verwijderen of markeren als waar.


Antwoord 26

Als u om de een of andere reden de @JsonIgnoreProperties-annotaties niet aan uw klas kunt toevoegen en u zich in een webserver/container zoals Jetty bevindt. U kunt de ObjectMapper maken en aanpassen in een aangepaste provider

import javax.ws.rs.ext.ContextResolver;
import javax.ws.rs.ext.Provider;
import com.fasterxml.jackson.annotation.JsonInclude.Include;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
@Provider
public class CustomObjectMapperProvider implements ContextResolver<ObjectMapper> {
    private ObjectMapper objectMapper;
    @Override
    public ObjectMapper getContext(final Class<?> cls) {
        return getObjectMapper();
    }
    private synchronized ObjectMapper getObjectMapper() {
        if(objectMapper == null) {
            objectMapper = new ObjectMapper();
            objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        }
        return objectMapper;
    }
}

Antwoord 27

Dit werkte perfect voor mij

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Antwoord 28

Dit is misschien niet hetzelfde probleem dat de OP had, maar als iemand hier kwam met dezelfde fout die ik had, dan zal dit hen helpen hun probleem op te lossen. Ik kreeg dezelfde fout als de OP toen ik een ObjectMapper van een andere afhankelijkheid gebruikte als de JsonProperty-annotatie.

Dit werkt:

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

Werkt NIET:

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

Antwoord 29

Ik heb dit probleem opgelost door simpelweg de handtekeningen van mijn setter- en getter-methoden van mijn POJO-klasse te wijzigen. Het enige wat ik hoefde te doen was de getObject-methode wijzigen om overeen te komen met wat de mapper zocht. In mijn geval had ik oorspronkelijk een getImageUrl, maar de JSON-gegevens hadden image_url, wat de mapper in de war bracht. Ik heb zowel mijn setter als getters gewijzigd in getImage_url en setImage_url.


Antwoord 30

De POJO moet worden gedefinieerd als

Responsklasse

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

Inpakklas

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

en mapper om waarde te lezen

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

Other episodes