Джексон с JSON: нераспознанное поле, не помеченное как игнорируемое - PullRequest
558 голосов
/ 20 декабря 2010

Мне нужно преобразовать определенную строку 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: java.io.StringReader@1198891; line: 1, column: 13] 
    (through reference chain: Wrapper["wrapper"])
 at org.codehaus.jackson.map.exc.UnrecognizedPropertyException
    .from(UnrecognizedPropertyException.java:53)

Ответы [ 34 ]

12 голосов
/ 20 декабря 2010

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

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

10 голосов
/ 13 июня 2012

Я попробовал описанный ниже метод, и он работает для чтения такого формата 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 голосов
/ 07 июня 2013

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

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

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

9 голосов
/ 16 ноября 2016

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

public Class Wrapper {
    @JsonProperty("wrapper")
    private List<Student> students;
    //getters & setters here
}
8 голосов
/ 16 апреля 2012

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

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

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

  1. Исправьте имя свойства либо в классе, либо в JSON.
  2. Аннотируйте переменную свойства согласно комментарию StaxMan.
  3. Аннотируйте сеттер (если он у вас есть)
5 голосов
/ 27 августа 2014

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

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"}]}
5 голосов
/ 12 апреля 2016

Ваш ввод

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

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

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

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

class Wrapper {
    List<Student> wrapper;
}
4 голосов
/ 19 мая 2015

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

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

4 голосов
/ 05 марта 2015

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

objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
4 голосов
/ 15 сентября 2014

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

@JsonIgnoreProperties(ignoreUnknown = true)

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

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

@JsonInclude(Include.NON_EMPTY)

Jackson 2.40,0

...