Мне нужно преобразовать определенную строку 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: java.io.StringReader@1198891; line: 1, column: 13]
(through reference chain: Wrapper["wrapper"])
at org.codehaus.jackson.map.exc.UnrecognizedPropertyException
.from(UnrecognizedPropertyException.java:53)
Вы можете использовать аннотацию уровня класса Джексона:
import com.fasterxml.jackson.annotation.JsonIgnoreProperties
@JsonIgnoreProperties
class { ... }
Он будет игнорировать все свойства, которые вы не определили в вашем POJO. Очень полезно, когда вы просто ищете пару свойств в JSON и не хотите писать полное отображение. Больше информации на сайте Джексона. Если вы хотите игнорировать любое не объявленное свойство, вы должны написать:
@JsonIgnoreProperties(ignoreUnknown = true)
Вы можете использовать
ObjectMapper objectMapper = getObjectMapper();
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Он игнорирует все свойства, которые не объявлены.
Первый ответ почти правильный, но необходимо изменить метод getter, а поле field - private (а не автоматически обнаружено); Кроме того, получатели имеют приоритет над полями, если оба они видны. (Есть способы сделать видимыми видимые поля тоже, но если вы хотите, чтобы getter там не так много точек)
Таким образом, getter должен быть либо назван getWrapper()
, либо аннотирован:
@JsonProperty("wrapper")
Если вы предпочитаете имя метода getter как есть.
используя Jackson 2.6.0, это сработало для меня:
private static final ObjectMapper objectMapper =
new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
и с настройкой:
@JsonIgnoreProperties(ignoreUnknown = true)
Это просто отлично сработало для меня
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.configure(
DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
@JsonIgnoreProperties(ignoreUnknown = true)
аннотации не было.
это может быть достигнуто двумя способами:
Отметьте 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)
Это работает лучше, чем все, пожалуйста, обратитесь к этому свойству.
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);
Если вы используете Jackson 2.0
ObjectMapper mapper = new ObjectMapper();
mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
В соответствии с 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)
Он работал у меня со следующим кодом:
ObjectMapper mapper =new ObjectMapper();
mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Джексон жалуется, потому что не может найти поле в своем классе Wrapper, которое называется "обертка". Это делает это, потому что ваш объект JSON имеет свойство, называемое "оберткой".
Я думаю, что исправление заключается в переименовании поля класса Wrapper в "wrapper" вместо "students".
Это решение является общим при чтении потоков json и необходимо получить только некоторые поля, в то время как поля, неправильно отображаемые в ваших классах доменов, можно игнорировать:
import org.codehaus.jackson.annotate.JsonIgnoreProperties;
@JsonIgnoreProperties(ignoreUnknown = true)
Подробное решение заключалось бы в использовании инструмента, такого как jsonschema2pojo, для автогенерации требуемых классов домена, таких как Student, из схемы json Response. Вы можете сделать последнюю с помощью любого онлайн-json для конвертера схемы.
Я пробовал метод ниже, и он работает для чтения 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
Надеюсь, что это поможет
{}
на панели инструментов для форматирования фрагментов кода.
Аннотировать участников курса как показано ниже, поскольку существует несоответствие в именах свойств json и свойства java
public Class Wrapper {
@JsonProperty("wrapper")
private List<Student> students;
//getters & setters here
}
Как никто другой не упомянул, думал, что я...
Проблема заключается в том, что ваша собственность в вашем JSON называется "оберткой", а ваша собственность в Wrapper.class называется "ученики".
Так что...
Ваш вход
{"wrapper":[{"id":"13","name":"Fred"}]}
указывает, что это объект с полем "обертка", который представляет собой сборник учащихся. Поэтому моя рекомендация была бы,
Wrapper = mapper.readValue(jsonStr , Wrapper.class);
где Wrapper
определяется как
class Wrapper {
List<Student> wrapper;
}
Я исправил эту проблему, просто изменив подписи методов setter и getter моего класса POJO. Все, что мне нужно было сделать, это изменить метод getObject, чтобы он соответствовал тому, что искал искатель. В моем случае у меня был исходный getImageUrl, но у данных JSON было image_url, которое выкидывало mapper. Я изменил оба моих сеттера и получателей на getImage_url и setImage_url.
Надеюсь, что это поможет.
Это отлично сработало для меня
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
Со своей стороны, единственная строка
@JsonIgnoreProperties(ignoreUnknown = true)
тоже не работает.
Просто добавьте
@JsonInclude(Include.NON_EMPTY)
Джексон 2.4.0
Либо изменить
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"}]}
Что сработало для меня, было сделать публичную собственность. Он решил проблему для меня.
Новый 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
в свой класс.
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);
wrappers
, а wrapper
.
установите, чтобы поля вашего класса не были приватными.
public Class Student {
public String name;
public String id;
//getters & setters for name & id here
}
Google привел меня сюда, и я был удивлен, увидев ответы... все предлагали обходить ошибку (которая всегда откусывает назад 4 раза позже в развитии), а не решать ее до тех пор, пока этот джентльмен не восстановится верой в SO!
objectMapper.readValue(responseBody, TargetClass.class)
используется для преобразования JSON строки в объект класса, Что не хватает в том, что TargetClass
должен иметь публичный get
тер /set
теров. То же самое и в фрагменте вопроса OP тоже! :)
через ломбок ваш класс, как показано ниже, должен работать!
@Data
@Builder
public class TargetClass {
private String a;
}
Это может быть очень поздний ответ, но просто изменение POJO на это должно решить строку json, предоставленную в задаче (так как входная строка не находится в вашем управлении, как вы сказали):
public class Wrapper {
private List<Student> wrapper;
//getters & setters here
}
В моем случае это было просто: объект JSON-сервиса REST-сервиса был обновлен (добавлено свойство), но объект JEST-объекта REST-клиента не был. Как только я обновил клиентский объект JSON, исключение "Unrecognized field..." исчезло.
Еще одна возможность - это свойство в application.properties spring.jackson.deserialization.fail-on-unknown-properties=false
, которое не потребует никаких других изменений кода в вашем приложении. И когда вы считаете, что договор является стабильным, вы можете удалить это свойство или отметить его как истинное.
Измените класс Wrapper на
public Class Wrapper {
@JsonProperty("wrapper") // add this line
private List<Student> students;
}
Это делается для того, чтобы распознать поле students
качестве ключа- wrapper
объекта json.
Также я лично предпочитаю использовать Lombok Annotations для Getters and Setters as
@Getter
@Setter
public Class Wrapper {
@JsonProperty("wrapper") // add this line
private List<Student> students;
}
Поскольку я не тестировал вышеуказанный код с Lombok и @JsonProperty
вместе, я предлагаю вам добавить следующий код в класс Wrapper, а также переопределить получателя и установщика по умолчанию для Lombok.
public List<Student> getWrapper(){
return students;
}
public void setWrapper(List<Student> students){
this.students = students;
}
Также проверьте это в списках десериализации, используя Джексон.
В моем случае ошибка возникла из-за следующей причины
Первоначально он работал нормально, затем я переименовал одну переменную, внесли изменения в код и дал мне эту ошибку.
Тогда я применил и джексон-невежественное свойство, но это не сработало.
Наконец, после переопределения методов getter и seters в соответствии с именем моей переменной эта ошибка была решена
Поэтому обязательно уточняйте получателей и сеттеров.
Вам нужно проверить все поля класса, в котором выполняется синтаксический анализ, сделать его таким же, как в исходном JSONObject
. Это помогло мне и в моем случае.
@JsonIgnoreProperties(ignoreUnknown = true)
ничего не помогло.
@JsonIgnoreProperties(ignoreUnknown = true)
определенно игнорирует свойства, которые не определены в Java-объекте, но присутствуют в JSON
Ваша строка json не является встроенной с отображенным классом. Измените строку ввода
String jsonStr = "{\"students\"\:[{\"id\":\"13\",\"name\":\"Fred\"}]}";
Или измените свой сопоставленный класс
public class Wrapper {
private List<Student> wrapper;
//getters & setters here
}
Вы должны просто изменить поле "Список" от "учеников" до "обертки" только json файла, и отобразитель отобразит его.
Я создал общественное поле, работал у меня. В вашем случае, как показано ниже:
public Class Student {
public String name;
public String id;
}
Map dummy<String,Student> = myClientResponse.getEntity(new GenericType<Map<String, Student>>(){});
а затемStudent myStudent = dummy.get("wrapper");