Джексон с JSON: нераспознанное поле, не помеченное как игнорируемое

Мне нужно преобразовать определенную строку JSON в объект Java. Я использую Джексона для обработки JSON. У меня нет контроля над вводом JSON (я читаю из веб-службы). Это мой входной JSON:

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

Вот упрощенный вариант использования:

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

Мой класс сущности:

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

Мой класс Wrapper - это, по сути, контейнерный объект для получения моего списка учеников:

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

Я продолжаю получать эту ошибку, и "обертка" возвращает null, Я не уверен, чего не хватает. Может кто-нибудь помочь, пожалуйста?

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)

33 ответа

Вы можете использовать аннотацию на уровне класса Джексона:

import com.fasterxml.jackson.annotation.JsonIgnoreProperties

@JsonIgnoreProperties
class { ... }

Он будет игнорировать все свойства, которые вы не определили в вашем POJO. Очень полезно, когда вы просто ищете пару свойств в JSON и не хотите писать полное отображение. Больше информации на сайте Джексона. Если вы хотите игнорировать любое не объявленное свойство, вы должны написать:

@JsonIgnoreProperties(ignoreUnknown = true)
765

Ты можешь использовать

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

Он будет игнорировать все свойства, которые не объявлены.

349

Первый ответ почти правильный, но необходимо изменить метод получения, а НЕ поле - поле является закрытым (и не определяется автоматически); кроме того, геттеры имеют приоритет над полями, если оба видны.(Есть также способы сделать приватные поля видимыми, но если вы хотите получить геттер, нет особого смысла)

Таким образом, получатель должен быть назван getWrapper()или помечены:

@JsonProperty("wrapper")

Если вы предпочитаете имя метода получения как есть.

115

Используя Джексон 2.6.0, это сработало для меня:

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

и с настройкой:

@JsonIgnoreProperties(ignoreUnknown = true)
61

Это просто отлично работает для меня

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

@JsonIgnoreProperties(ignoreUnknown = true) аннотации не было.

38

Это может быть достигнуто 2 способами:

  1. Отметьте POJO, чтобы игнорировать неизвестные свойства

    @JsonIgnoreProperties(ignoreUnknown = true)
    
  2. Сконфигурируйте ObjectMapper, который сериализует / десериализует POJO/json, как показано ниже:

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

Это работает лучше, чем все, пожалуйста, обратитесь к этой собственности.

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

Если вы используете Джексон 2.0

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

Согласно документу вы можете игнорировать выбранные поля или все неизвестные поля:

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

Это сработало у меня со следующим кодом:

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

Джексон жалуется, потому что не может найти поле в вашем классе Wrapper, которое называется "обертка". Это происходит потому, что у вашего объекта JSON есть свойство, называемое "обертка".

Я думаю, что решение состоит в том, чтобы переименовать поле вашего класса Wrapper в "обертку" вместо "студентов".

12

Я попробовал метод ниже, и он работает для чтения такого формата JSON с Джексоном. Используйте уже предложенное решение: аннотирование геттера с помощью @JsonProperty("wrapper")

Ваш класс обертки

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

Мое предложение класса обертки

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

Это, однако, даст вам вывод формата:

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

Также для получения дополнительной информации обратитесь к https://github.com/FasterXML/jackson-annotations

Надеюсь это поможет

10

Это решение является общим при чтении потоков JSON и требует получения только некоторых полей, в то время как поля, не отображенные в ваших доменных классах, могут быть проигнорированы:

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

Подробным решением будет использование такого инструмента, как jsonschema2pojo, для автоматического создания необходимых классов предметной области, таких как Student, из схемы ответа json. Это можно сделать с помощью любого онлайн-конвертера json в схему.

9

Как никто не упомянул, думал, что я...

Проблема в том, что ваша собственность в вашем JSON называется "оболочкой", а ваша собственность в Wrapper.class называется "студентами".

Так что либо...

  1. Исправьте имя свойства в классе или JSON.
  2. Аннотируйте вашу переменную свойства согласно комментарию StaxMan.
  3. Аннотируйте сеттер (если он у вас есть)
8

Аннотируйте полевых студентов, как показано ниже, поскольку в именах свойств json и java есть несоответствие

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

Ваш вклад

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

указывает, что это объект с полем с именем "обертка", который является коллекцией студентов. Так что моя рекомендация будет,

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

где Wrapper определяется как

class Wrapper {
    List<Student> wrapper;
}
5

Либо изменить

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

в

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

---- или же ----

Измените строку JSON на

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

То, что работало для меня, должно было сделать собственность публичной. Это решило проблему для меня.

4

Я исправил эту проблему, просто изменив подписи моих методов установки и получения моего класса POJO. Все, что мне нужно было сделать, это изменить метод getObject, чтобы он соответствовал тому, что искал маппер. В моем случае у меня изначально был getImageUrl, но у данных JSON был image_url, который отбрасывал маппер. Я изменил и мои сеттеры, и геттеры на getImage_url и setImage_url.

Надеюсь это поможет.

4

С моей стороны, единственная линия

@JsonIgnoreProperties(ignoreUnknown = true)

тоже не работал

Просто добавь

@JsonInclude(Include.NON_EMPTY)

Джексон 2.4.0

4

Это отлично сработало для меня

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

POJO должен быть определен как

Класс ответа

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

Класс Wrapper

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

и картограф для чтения значения

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

Новый Firebase Android внес некоторые огромные изменения; ниже копия документа:

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

Обновите ваши объекты модели Java

Как и в 2.x SDK, база данных Firebase автоматически преобразует объекты Java, которые вы передаете DatabaseReference.setValue() в JSON и может читать JSON в объекты Java, используя DataSnapshot.getValue(),

В новом SDK при чтении JSON в объект Java с DataSnapshot.getValue() неизвестные свойства в JSON теперь по умолчанию игнорируются, поэтому вам больше не нужно @JsonIgnoreExtraProperties(ignoreUnknown=true),

Чтобы исключить поля / получатели при записи объекта Java в JSON, аннотация теперь называется @Exclude вместо @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)

Если в вашем JSON есть дополнительное свойство, которого нет в вашем классе Java, вы увидите это предупреждение в файлах журнала:

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

Вы можете избавиться от этого предупреждения, поставив @IgnoreExtraProperties аннотации к вашему классу. Если вы хотите, чтобы база данных Firebase вела себя так же, как в 2.x SDK, и выдает исключение, если есть неизвестные свойства, вы можете поставить @ThrowOnExtraProperties аннотации к вашему классу.

3

Сделайте общедоступными ваши поля класса, а не частными.

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

Это может быть очень поздний ответ, но простое изменение POJO на это должно решить строку json, представленную в задаче (поскольку входная строка не находится под вашим контролем, как вы сказали):

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

В моем случае это было просто: объект JSON REST-сервиса был обновлен (добавлено свойство), а объект JSON REST-клиента не был. Как только я обновил объект клиента JSON, исключение "Нераспознанное поле..." исчезло.

1

Google привел меня сюда, и я был удивлен, увидев ответы... все предложили обойти ошибку (которая всегда откатывается на 4 раза позже в процессе разработки), а не решать ее до тех пор, пока этот джентльмен не будет восстановлен верой в ТАК!

objectMapper.readValue(responseBody, TargetClass.class)

используется для преобразования строки json в объект класса, чего не хватает, так это того, что TargetClass должен иметь общественность getтер / setОслабляет. То же самое отсутствует в фрагменте вопроса ОП тоже!:)

через ломбок твой класс как ниже должен работать!!

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

Еще одна возможность - это свойство в application.propertiesspring.jackson.deserialization.fail-on-unknown-properties=false, который не потребует никакого другого изменения кода в вашем приложении. И когда вы считаете, что договор является стабильным, вы можете удалить это свойство или отметить его как истинное.

1

В моем случае ошибка произошла по следующей причине

  • Первоначально он работал нормально, затем я переименовал одну переменную, внес изменения в код, и это дало мне эту ошибку.

  • Тогда я применил Джексона невежественное свойство также, но это не сработало.

  • Наконец, после переопределения моих методов получения и установки в соответствии с именем моей переменной эта ошибка была устранена

Так что убедитесь, что заново дорабатываете геттеры и сеттеры тоже.

0

Вам просто нужно изменить поле List с "student" на "wrapper", просто файл json, и маппер найдет его.

0
Другие вопросы по тегам