#java #jackson #deserialization
#java #джексон #десериализация
Вопрос:
Я использую Jackson для десериализации XML-файла:
public SomeClassDTO deserializeXML(String pathToFile) {
File file = new File(pathToFile);
XmlMapper xmlMapper = new XmlMapper();
String xml = null;
try {
xml = inputStreamToString(new FileInputStream(file));
xml = xml.replaceAll("\s ","");
} catch (FileNotFoundException fileNotFoundException) {
logger.error("file could not be found");
}
SomeClassDTO value = new SomeClassDTO();
try {
value = xmlMapper.readValue(xml, SomeClassDTO.class);
} catch (JsonProcessingException jsonProcessingException) {
logger.error("Deserialization failed");
jsonProcessingException.printStackTrace();
}
return value;
}
public String inputStreamToString(InputStream is) {
StringBuilder sb = new StringBuilder();
String line;
try (BufferedReader br = new BufferedReader(new InputStreamReader(is))) {
while ((line = br.readLine()) != null) {
sb.append(line);
}
} catch (IOException ioException) {
logger.error("Die Konfigurationsdatei kann nicht gelesen werden.");
ioException.printStackTrace();
}
return sb.toString();
}
Кроме того, вот как выглядит SomeClassDTO следующим образом:
import java.util.ArrayList;
import java.util.List;
public class SomeClassDTO {
private List<Book> books = new ArrayList<>();
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
}
А вот как выглядит Книжный класс:
class Book {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
И это XML-файл, который я пытаюсь прочитать:
<SomeClassDTO>
<books>
<Boosdfsk>
<name>sldjfks</name>
</Boosdfsk>
<Book>
<name>blablub</name>
</Book>
</books>
</SomeClassDTO>
Как вы можете видеть, совершенно необязательно, если я напишу «Book» или «Booksdhfsj» или что-то еще.
Этот факт действительно сбивает меня с толку.
Комментарии:
1. Насколько я знаю, существует конфигурация / свойство с именем «deserialization-fail-on-unknown-properties» или что-то подобное, которое по умолчанию равно false, что означает, что если во время десериализации оно встречает свойство, которое оно не может сопоставить (например, Boosdfsk), оно просто проигнорирует их, а не выдаст ошибку. Таким образом, результат вашей десериализации должен быть таким же, как если бы вы удалили неправильный
<Boosdfsk>
тег.2. Если я нашел фрагмент кода
xmlMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true);
, к сожалению, он все еще не работает.
Ответ №1:
Поскольку Jackson имеет достаточно информации о десериализованном типе путем проверки books
свойства, ему не нужно ничего знать о теге, используемом для каждого дочернего объекта. Он знает, что каждый дочерний элемент будет a Book
.
Вы можете увидеть соответствующий разговор в этом выпуске GitHub: https://github.com/FasterXML/jackson-dataformat-xml/issues/322
Короче говоря, любые аннотации, которые вы используете для настройки имени тега, используемого для Book
, будут использоваться только для сериализации.
Если вы хотите читать только Book
s, одним из вариантов было бы создать класс Books
, который считывает список книг как развернутый список.