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

Мне нужно преобразовать определенную строку JSON в объект Java. Я использую Jackson для обработки 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
}

Класс My Wrapper - это в основном контейнерный объект, чтобы получить список моих учеников:

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

Я продолжаю получать эту ошибку, а "wrapper" возвращает 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)

Ответ 1

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

import com.fasterxml.jackson.annotation.JsonIgnoreProperties

@JsonIgnoreProperties
class { ... }

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

@JsonIgnoreProperties(ignoreUnknown = true)

Ответ 2

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

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

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

Ответ 3

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

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

@JsonProperty("wrapper")

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

Ответ 4

используя Jackson 2.6.0, это сработало для меня:

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

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

@JsonIgnoreProperties(ignoreUnknown = true)

Ответ 5

это может быть достигнуто двумя способами:

  • Отметьте POJO для игнорирования неизвестных свойств

    @JsonIgnoreProperties(ignoreUnknown = true)
    
  • Настройте 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) 
    

Ответ 6

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

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

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

Ответ 7

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

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

Ответ 8

Если вы используете Jackson 2.0

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

Ответ 9

В соответствии с doc вы можете игнорировать выбранные поля или все поля uknown:

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

Ответ 10

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

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

Ответ 11

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

Я думаю, что исправление заключается в переименовании поля класса Wrapper в "wrapper" вместо "students".

Ответ 12

Я пробовал метод ниже, и он работает для чтения JSON-формата с помощью Jackson. Используйте уже предложенное решение: аннотировать геттер с @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

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

Ответ 13

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

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

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

Ответ 14

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

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

Ответ 15

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

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

Так что...

  • Исправить имя свойства в классе или JSON.
  • Аннотировать вашу переменную свойства в соответствии с комментарием StaxMan.
  • Аннотировать установщик (если он у вас есть)

Ответ 16

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

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

to

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

---- или ----

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

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

Ответ 17

Ваш вход

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

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

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

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

class Wrapper {
    List<Student> wrapper;
}

Ответ 18

установите, чтобы поля вашего класса не были приватными.

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

Ответ 19

Что сработало для меня, было сделать публичную собственность. Он решил проблему для меня.

Ответ 20

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

@JsonIgnoreProperties(ignoreUnknown = true)

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

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

@JsonInclude(Include.NON_EMPTY)

Джексон 2.4.0

Ответ 21

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

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

Ответ 22

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

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

Ответ 23

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

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

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

Как и в случае с 2.x SDK, Firebase Database автоматически преобразует объекты 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 аннотацию @IgnoreExtraProperties. Если вы хотите, чтобы база данных Firebase вела себя так, как в SDK 2.x, и генерирует исключение, если есть неизвестные свойства, вы можете поместить аннотацию @ThrowOnExtraProperties в свой класс.

Ответ 24

POJO следует определять как

Класс ответа

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

Класс обертки

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

и mapper для чтения значения

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

Ответ 25

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

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

Ответ 26

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

Ответ 27

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

objectMapper.readValue(responseBody, TargetClass.class)

используется для преобразования JSON строки в объект класса, Что не хватает в том, что TargetClass должен иметь публичный get тер /set теров. То же самое и в фрагменте вопроса OP тоже! :)

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

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

Ответ 28

Возможно, это не та же проблема, что и у ОП, но в случае, если кто-то попал сюда с той же ошибкой, что и я, это поможет им решить их проблему. Я получил ту же ошибку, что и OP, когда использовал ObjectMapper из другой зависимости, что и аннотация JsonProperty.

Это работает:

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

НЕ работает:

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

Ответ 29

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

Ответ 30

Вы должны просто изменить поле "Список" от "учеников" до "обертки" только json файла, и отобразитель отобразит его.