Джексон с 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 ]

4 голосов
/ 25 мая 2014

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

3 голосов
/ 13 июня 2018

set public поля вашего класса не private .

public Class Student { 
    public String name;
    public String id;
    //getters & setters for name & id here
}
3 голосов
/ 01 апреля 2014

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

Класс ответа

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

Класс оболочки

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

и преобразователь для чтения значения

Response response = mapper.readValue(jsonStr , Response.class);
3 голосов
/ 31 января 2019

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

3 голосов
/ 08 июля 2016

В новый 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.

2 голосов
/ 24 августа 2017

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

public class Wrapper {
    private List<Student> wrapper;
    //getters & setters here
}
1 голос
/ 13 февраля 2018

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

objectMapper.readValue(responseBody, TargetClass.class)

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

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

@Data
@Builder
public class TargetClass {
    private String a;
}
1 голос
/ 13 июня 2016

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

1 голос
/ 11 июня 2019

Возможно, это не та же проблема, что и у ОП, но в случае, если кто-то попал сюда с той же ошибкой, что и я, это поможет им решить их проблему. Я получил ту же ошибку, что и 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
0 голосов
/ 19 июня 2016

Ваша строка json не соответствует встроенному классу.Измените строку ввода

String jsonStr = "{\"students\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";

Или измените свой отображенный класс

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