При синтаксическом анализе строки JSON, полученной от одного из наших веб-сервисов RESTful, я получал эту ошибку «Исключение в потоке« main »com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: нераспознанное поле« person »(класс Hello $ Person), а не помечен как игнорируемый » .
После некоторых исследований я обнаружил, что это одна из распространенных ошибок при анализе документа JSON с использованием библиотеки с открытым исходным кодом Jackson в приложении Java. В сообщениях об ошибках говорится, что в нашем случае невозможно найти подходящее имя свойства с именем person, давайте сначала рассмотрим JSON, который мы пытаемся проанализировать, класс, который мы используем для представления документа JSON, и ошибку само сообщение
Сообщение об ошибке:
| 1 | Exception inthread "main"com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: <b>Unrecognized field "person"</b> (class Hello$Person), not marked as ignorable (4 known properties: , "id", "city", "name", "phone"]) | 
В сообщениях об ошибках говорится, что он может определить атрибуты id, city, name и phone в классе Person, но не может найти поле «person».
Наш класс POJO выглядит следующим образом:
| 01 02 03 04 05 06 07 08 09 10 11 12 13 | classPerson{privateintid;privateString name;privateString city;privatelongphone;.....} | 
и строка JSON:
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | {"person": [{"id": "11","name": "John","city": "NewYork","phone": 7647388372}]} | 
Если вы посмотрите внимательно, поле «person» указывает на массив JSON, а не на объект, что означает, что его нельзя напрямую сопоставить с классом person.
Как решить эту проблему
Вот шаги, чтобы решить эту проблему и избавиться от этой ошибки:
1) Сконфигурируйте ObjectMapper Джексона, чтобы он не завершался ошибкой, когда привлекает неизвестные свойства
 Вы можете сделать это, отключив свойство D eserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES как показано ниже: 
| 1 2 3 4 5 6 7 8 9 | //Jackson code to convert JSON String to Java objectObjectMapper objectMapper = new ObjectMapper();objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);Person p = objectMapper.readValue(JSON, Person.class);System.out.println(p); | 
Теперь ошибка исчезнет, но вывод не соответствует ожидаемому, он выведет следующее:
| 1 | Person [id=0, name=null, city=null, phone=0] | 
  Вы можете видеть, что класс Person не создан должным образом, соответствующие атрибуты имеют значение null, даже если строка JSON содержит его значение. 
  Причина в том, что JSON String содержит массив JSON , поле person указывает на массив, и в классе Person нет соответствующего ему поля. 
  Чтобы правильно проанализировать строку JSON, нам нужно создать класс-оболочку Community которого будет атрибут для хранения массива Person, как показано ниже: 
| 01 02 03 04 05 06 07 08 09 10 11 12 | staticclassCommunity {  privateList<Person> person;  publicList<Person> getPerson() {    returnperson;  }  publicvoidsetPerson(List<Person> person) {    this.person = person;  }} | 
  Теперь мы преобразуем строку JSON в этот класс Community и напечатаем каждого человека из списка, как показано ниже: 
| 01 02 03 04 05 06 07 08 09 10 11 | ObjectMapper objectMapper = newObjectMapper();//objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);Community c = objectMapper.readValue(JSON, Community.class);for(Person p : c.getPerson()) {System.out.println(p);} | 
Это распечатает данные человека должным образом, как показано ниже:
| 1 | Person [id=11, name=John, city=NewYork, phone=7647388372] | 
Теперь, возвращаясь к более общей ситуации, когда новое поле добавляется в JSON, но недоступно в вашем классе Person , давайте посмотрим, что произойдет.
Предположим, что наша строка JSON для разбора выглядит следующим образом:
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | {"person": [{"id": "11","name": "John","city": "NewYork","phone": 7647388372,"facebook": "JohnTheGreat"}]} | 
Когда вы запустите ту же программу с этой строкой JSON , вы получите следующую ошибку:
Опять же, Джексон не может распознать новое свойство «Facebook». Теперь мы можем игнорировать это свойство, отключив функцию, которая сообщает Джексону об отказе в неизвестном свойстве, как показано ниже:
| 1 2 3 4 5 | ObjectMapper objectMapper = new ObjectMapper();objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);Community c = objectMapper.readValue(JSON, Community.class); | 
И это правильно напечатает класс person, как показано ниже:
| 1 | Person [id=11, name=John, city=NewYork, phone=7647388372] | 
  Кроме того, вы также можете использовать аннотацию @JsonIgnoreProperties чтобы игнорировать необъявленные свойства. 
  @JsonIgnoreProperties — это аннотация уровня класса в Джексоне, и она будет игнорировать все свойства, которые вы не определили в своем POJO.  Очень полезно, когда вы просто ищете пару свойств в JSON и не хотите писать полное отображение. 
Эта аннотация обеспечивает контроль на уровне класса, т.е. вы можете сказать Джексону, что для этого класса, пожалуйста, игнорируйте любой атрибут, не определенный при выполнении
| 1 | @JsonIgnoreProperties(ignoreUnknown = true) | 
Итак, наш класс Person теперь выглядит так:
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 | @JsonIgnoreProperties(ignoreUnknown = true)staticclassPerson{privateintid;privateString name;privateString city;privatelongphone;......} | 
Пример программы
| 001 002 003 004 005 006 007 008 009 010 011 012 013 014 015 016 017 018 019 020 021 022 023 024 025 026 027 028 029 030 031 032 033 034 035 036 037 038 039 040 041 042 043 044 045 046 047 048 049 050 051 052 053 054 055 056 057 058 059 060 061 062 063 064 065 066 067 068 069 070 071 072 073 074 075 076 077 078 079 080 081 082 083 084 085 086 087 088 089 090 091 092 093 094 095 096 097 098 099 100 | importjava.io.IOException;importjava.util.List;importcom.fasterxml.jackson.core.JsonParseException;importcom.fasterxml.jackson.databind.DeserializationFeature;importcom.fasterxml.jackson.databind.JsonMappingException;importcom.fasterxml.jackson.databind.ObjectMapper;/* * { "person": [ { "id": "11", "name": "John", "city": "NewYork", "phone": 7647388372 } ] }  */publicclassHello {  privatestaticString JSON = "{\r\n"+ " \"person\": [\r\n"+ " {\r\n"      + " \"id\": \"11\",\r\n"+ " \"name\": \"John\",\r\n"      + " \"city\": \"NewYork\",\r\n"+ " \"phone\": 7647388372,\r\n"      + " \"facebook\": \"JohnTheGreat\"\r\n"+ " }\r\n"+ " ]\r\n"+ " } ";  publicstaticvoidmain(String args[]) throwsJsonParseException,      JsonMappingException, IOException {    ObjectMapper objectMapper = newObjectMapper();    objectMapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);    Community c = objectMapper.readValue(JSON, Community.class);    for(Person p : c.getPerson()) {      System.out.println(p);    }  }  staticclassCommunity {    privateList<Person> person;    publicList<Person> getPerson() {      returnperson;    }    publicvoidsetPerson(List<Person> person) {      this.person = person;    }  }  staticclassPerson {    privateintid;    privateString name;    privateString city;    privatelongphone;    publicintgetId() {      returnid;    }    publicvoidsetId(intid) {      this.id = id;    }    publicString getName() {      returnname;    }    publicvoidsetName(String name) {      this.name = name;    }    publicString getCity() {      returncity;    }    publicvoidsetCity(String city) {      this.city = city;    }    publiclonggetPhone() {      returnphone;    }    publicvoidsetPhone(longphone) {      this.phone = phone;    }    @Override    publicString toString() {      return"Person [id="+ id + ", name="+ name + ", city="+ city          + ", phone="+ phone + "]";    }  }} | 
Когда я запускаю первую версию этой программы, меня встречает следующая ошибка:
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 | Exception inthread "main"com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found fortype[simple type, class Hello$Person]: can not instantiate from JSON object (need to add/enabletypeinformation?)at [Source: java.io.StringReader@5e329ba8; line: 2, column: 3]at com.fasterxml.jackson.databind.JsonMappingException.from(JsonMappingException.java:164)at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.deserializeFromObjectUsingNonDefault(BeanDeserializerBase.java:984)at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:276)at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)at Hello.main(Hello.java:40) | 
  Эта ошибка произошла из-за того, что мой вложенный класс Person не был статичным, что означает, что его нельзя создать из-за наличия экземпляра внешнего класса.  Проблема решена после того, как класс Person статическим . 
  Если вы не знакомы с этой деталью раньше, я предлагаю вам проверить 
  Основы Java: Базовая платформа , бесплатный курс от Pluralsight, чтобы узнать больше о таких деталях языка программирования Java.  Вы можете подписаться на бесплатную пробную версию, которая дает вам 10-дневный доступ, достаточный для изучения всей Java бесплатно. 
Теперь посмотрим на реальную ошибку:
| 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 | Exception inthread "main"com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: <b>Unrecognized field "person"(class Hello$Person), not marked as ignorable</b> (4 known properties: , "id", "city", "name", "phone"])at [Source: java.io.StringReader@4fbc9499; line: 2, column: 14] (through reference chain: Person["person"])at com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException.from(UnrecognizedPropertyException.java:79)at com.fasterxml.jackson.databind.DeserializationContext.reportUnknownProperty(DeserializationContext.java:555)at com.fasterxml.jackson.databind.deser.std.StdDeserializer.handleUnknownProperty(StdDeserializer.java:708)at com.fasterxml.jackson.databind.deser.BeanDeserializerBase.handleUnknownProperty(BeanDeserializerBase.java:1160)at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserializeFromObject(BeanDeserializer.java:315)at com.fasterxml.jackson.databind.deser.BeanDeserializer.deserialize(BeanDeserializer.java:121)at com.fasterxml.jackson.databind.ObjectMapper._readMapAndClose(ObjectMapper.java:2888)at com.fasterxml.jackson.databind.ObjectMapper.readValue(ObjectMapper.java:2034)at Hello.main(Hello.java:40) | 
Когда вы запустите финальную версию программы, вы увидите следующий вывод:
| 1 | Person [id=11, name=John, city=NewYork, phone=7647388372] | 
Это означает, что мы можем успешно проанализировать JSON, содержащий неизвестные атрибуты в Джексоне.
Как скомпилировать и запустить эту программу?
Вы можете просто скопировать вставить код в вашу любимую IDE, например, Eclipse, чтобы скомпилировать и запустить программу.
В Eclipse вам даже не нужно создавать файл класса, потому что он автоматически создаст класс и пакет, если вы скопируете и вставите код в проект Java.
  Если Eclipse является вашей основной IDE и вы хотите узнать больше о таких советах по производительности, я предлагаю вам проверить 
  Экскурсия «Затмение» — часть 1 и 2 Тод Джентилл . 
Это бесплатный онлайн-курс для изучения как основных, так и расширенных возможностей Eclipse IDE, о которых должен знать каждый разработчик Java. Вы можете получить доступ к этому курсу, подписавшись на бесплатную пробную версию, которая дает вам 10-дневный доступ ко всей библиотеке Pluralsight, одной из самых ценных коллекций для изучения программирования и других технологий. Кстати, 10 дней более чем достаточно для изучения Java и Eclipse вместе.
В любом случае, после копирования вставьте код, все, что вам нужно сделать, это включить зависимость Maven в ваш файл pom.xml или вручную загрузить требуемый JAR-файл для библиотеки с открытым исходным кодом Jackson .
Для пользователей Maven
Вы можете добавить следующую зависимость Maven к pom.xml вашего проекта, а затем выполнить команду mvn build или mvn install для компиляции:
| 1 2 3 4 5 | <dependency>  <groupId>com.fasterxml.jackson.core</groupId>  <artifactId>jackson-databind</artifactId>  <version>2.2.3</version></dependency> | 
  Эта зависимость требует jackson-annotations jackson-core и jackson-annotations но Maven автоматически загрузит их для вас. 
Загрузка JAR вручную
Если вы не используете Maven или какой-либо другой инструмент сборки eggradle, вы можете просто зайти в центральную библиотеку Maven и загрузить следующие три JAR-файла и включить их в ваш путь к классам:
| 1 2 3 | jackson-databind-2.2.3.jarjackson-core-2.2.3.jarjackson-annotations-2.2.3.jar | 
  После того, как вы успешно скомпилировали класс, вы можете запустить их, как и любую другую программу на Java в Eclipse, как показано здесь, или вы можете запустить файл JAR с помощью командной строки, как показано 
  здесь 
  Короче говоря, ошибка « com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: нераспознанное поле XXX, не помеченное как игнорируемое» возникает при попытке проанализировать JSON для объекта Java, который не содержит все поля, определенные в JSON.  Эту ошибку можно устранить, отключив функцию Джексона, которая сообщает об ошибке при обнаружении неизвестных свойств, или используя аннотацию @JsonIgnoreProperties на уровне класса. 
Дальнейшее обучение
- Введение в Spring MVC
- ОТДЫХ с Весной Евгений Параскив
- RESTFul Сервисы в Java с использованием Джерси
Спасибо за чтение этой статьи до сих пор. Если вам нравится мое объяснение, поделитесь с друзьями и коллегами. Если у вас есть какие-либо вопросы или пожелания, напишите нам.
| См. Оригинальную статью здесь: Ошибка синтаксического анализа JSON Джексона — UnrecognizedPropertyException: нераспознанное поле, не помеченное как игнорируемое [решено] Мнения, высказанные участниками Java Code Geeks, являются их собственными. | 


