10

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

21

У меня возникла проблема с преобразованием определенной строки 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;
    //геттеры и сеттеры для name и id здесь
}

Мой класс Wrapper представляет собой контейнер для списка студентов:

public class Wrapper {
    private List<Student> students;
    //геттеры и сеттеры здесь
}

Каждый раз при выполнении кода возникает следующая ошибка, и переменная wrapper возвращает 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"])

Заранее спасибо за помощь!

5 ответ(ов)

7

Вы можете использовать следующий код:

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

Этот код позволит игнорировать все свойства, которые не объявлены в вашем классе.

1

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

Таким образом, геттер должен либо называться getWrapper(), либо быть аннотирован с помощью:

@JsonProperty("wrapper")

Если вы предпочитаете оставить название метода-геттера прежним.

1

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

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

Также можно использовать аннотацию:

@JsonIgnoreProperties(ignoreUnknown = true)

Эти подходы помогут игнорировать неизвестные свойства при десериализации.

0

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

  1. Использовать аннотацию для игнорирования неизвестных свойств в вашем POJO:

    @JsonIgnoreProperties(ignoreUnknown = true)
    
  2. Настроить объект ObjectMapper, чтобы он серилизовал/десерилизовал ваш POJO/JSON следующим образом:

    ObjectMapper mapper = new ObjectMapper();            
    // для Jackson версии 1.X        
    mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    // для Jackson версии 2.X
    mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
    

Оба способа помогут избежать ошибок при обработке неизвестных свойств в JSON. Выберите тот, который лучше вписывается в вашу ситуацию.

0

Добавление сеттеров и геттеров решило проблему. Я понял, что настоящая проблема заключалась не в том, чтобы подавить или игнорировать ошибку, а в том, как ее действительно исправить. Я получил ошибку "Неизвестное поле.. не отмечено как игнорируемое.."

Хотя я использовал следующую аннотацию вверху класса, это не позволяло корректно обработать JSON-объект и получить входные данные:

@JsonIgnoreProperties(ignoreUnknown = true)

Затем я осознал, что не добавил сеттеры и геттеры. После их добавления в "Wrapper" и "Student" всё заработало как надо.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь