Ваша проблема немного сложна, потому что вам нужно решить несколько вопросов.Давайте начнем решать их один за другим.
1.Модель не подходит для XML
полезной нагрузки.
Прежде всего, вам необходимо создать модель, которая соответствует вашему payload
.Это не зависит от формата, потому что для JSON
и XML
это будет почти одинаково.Для этого я предлагаю всегда начинать с процесса сериализации.Намного проще построить модель в Java
и попытаться ее сериализовать.В случае, если он не выглядит так, как ожидалось, вам нужно обновить модель.Вы повторяете эти шаги: update
и serialise
, пока не найдете действительную модель.После этого вы можете без проблем десериализовать данный payload
.
2.Аннотации Джексона.
Несмотря на то, что аннотации Jackson
велики, не используйте их без причины.Если свойство POJO
совпадает с именем узла в XML
, вам не нужно добавлять аннотацию JacksonXmlProperty
.Вы должны добавить его, когда имена в POJO
и payload
различны.В других случаях это усложняет структуру POJO
.Мы должны сделать это как можно проще.Вам нужно использовать одну хитрую аннотацию: JacksonXmlElementWrapper
.Он используется, когда у нас есть коллекции узлов, но они развернуты.
После этих двух простых абзацев, чтобы не десериализовать ваш случай.Нам нужно расширить вашу POJO
структуру, и она должна выглядеть следующим образом:
class Dataset {
private LocalDateTime date;
@JacksonXmlProperty(localName = "element")
@JacksonXmlElementWrapper(useWrapping = false)
private List<Element> elements;
public LocalDateTime getDate() {
return date;
}
public void setDate(LocalDateTime date) {
this.date = date;
}
public List<Element> getElements() {
return elements;
}
public void setElements(List<Element> element) {
this.elements = element;
}
@Override
public String toString() {
return "Dataset{" +
"date=" + date +
", element=" + elements +
'}';
}
}
class Element {
private Long id;
private String name;
private Long age;
private RegDate regdate;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getAge() {
return age;
}
public void setAge(Long age) {
this.age = age;
}
public RegDate getRegdate() {
return regdate;
}
public void setRegdate(RegDate regdate) {
this.regdate = regdate;
}
@Override
public String toString() {
return "ElementXML{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
", regdate=" + regdate.getDate() +
'}';
}
}
class RegDate {
private LocalDateTime date;
public RegDate() {
this(null);
}
public RegDate(LocalDateTime date) {
this.date = date;
}
public LocalDateTime getDate() {
return date;
}
public void setDate(LocalDateTime date) {
this.date = date;
}
@Override
public String toString() {
return "RegDate{" +
"date=" + date +
'}';
}
}
И пример использования:
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.dataformat.xml.XmlMapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlElementWrapper;
import com.fasterxml.jackson.dataformat.xml.annotation.JacksonXmlProperty;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
public class XmlMapperApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.xml").getAbsoluteFile();
JavaTimeModule module = new JavaTimeModule();
module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ISO_DATE_TIME));
XmlMapper xmlMapper = new XmlMapper();
xmlMapper.registerModule(module);
xmlMapper.enable(SerializationFeature.INDENT_OUTPUT);
Dataset dataset = xmlMapper.readValue(jsonFile, Dataset.class);
dataset.getElements().forEach(System.out::println);
}
}
Над отпечатками кода:
ElementXML{id=1, name='Stuart', age=34, regdate=2017-10-25T09:13:54}
ElementXML{id=2, name='Lora', age=12, regdate=2017-10-25T09:13:54}
ElementXML{id=3, name='Ben', age=50, regdate=2017-10-25T09:13:54}
Два дополнительных комментария к приведенному выше коду.Когда вы работаете с java.time.*
классами и Jackson
, лучше начать с регистрации JavaTimeModule
, которая поступает из модуля jackson-datatype-jsr310 .Поскольку мы используем его, мы можем указать ему использовать ISO_DATE_TIME
форматирование для LocalDateTime
классов.В других ответах вы можете найти пример, где используется JsonFormat
аннотация.Это также хорошее решение, но когда все даты имеют одинаковый формат, гораздо проще определить его.
Для получения дополнительной информации читайте: