Spring MVC - получение объектов XML и десериализация в коллекцию - PullRequest
0 голосов
/ 23 мая 2018

Я пытаюсь десериализовать полезную нагрузку XML (тело сообщения SOAP, но не более) с определенной иерархией тегов / объектов.При попытке объединить развернутые объекты в список выдается исключение MismatchedInputException.

Пример полезной нагрузки

<libraryRequest>
  <libraryProfile>
    <libraryId>
    <libraryName>
    <newBookInfo>
      <bookId>...</bookId>
      <bookTitle>...</bookTitle>
      <datePublished>...</datePublished>
    </newBookInfo>
    <currentBooks>
      <bookId>...</bookId>
      <bookTitle>...<bookTitle>
      <datePublished>...</datePublished>
    </currentBooks>
    <currentBooks>
      <bookId>...</bookId>
      <bookTitle>...<bookTitle>
      <datePublished>...</datePublished>
    </currentBooks>
    <currentBooks>...</currentBooks>
  </libraryProfile>
</libraryRequest>

Java-объекты

public class LibraryRequest {
    private LibraryProfile libraryProfile;
    @XmlElement(name = "libraryProfile")
    public LibraryProfile getLibraryProfile(){
    ...
    }
// setters

public class LibraryProfile {
    // constructors, getters & setters for primitive types 

    private List<BookInfo> bookInfos;
    public List<BookInfo> getBookInfo(){
        return this.BookInfos;
    }
    // rest of the functions

Моя проблема заключается в том, что я не знаю, сколько тегов currentBooks попадет в полезную нагрузку XML, иони не входят в элемент обертки.Мне нужно отслеживать каждый элемент currentBook, поэтому я использовал коллекцию, но я не могу правильно заполнить коллекцию информацией, содержащейся в тегах currentBooks.

Смогу ли я использовать JAXB для группировки последовательности XML в коллекцию / список Java, и если нет, то смогу ли я использовать функцию XML Джексона для группировки развернутых тегов XML в коллекцию Java?

Основная цель - использовать, чтобы запрос XML поступал в Spring Controller и правильно десериализовывал последовательность XML в список / коллекцию Java.Любой совет поможет.

Я использую Spring Boot 1.5.8 (более поздняя версия доставляла мне проблемы по-другому) и версию Jackson 2.9.5

1 Ответ

0 голосов
/ 23 мая 2018

Это основано на объяснении XmlElement от actimem.com .

Механика объяснила: - @XmlElement требуется, только если имя поля не равно имени тега xml,- Если вы хотите переименовать ваше поле newBookInfo в newestBook, но без изменения xml вы просто переименуете свое поле и аннотируете его с помощью @XmlElement(name="newBookInfo") - @XmlElementWrapper явно не используется, чтобы рекомендовать JAXB поискатьтеги списка непосредственно в родительском узле

Классы представления XML Book

@XmlAccessorType(XmlAccessType.FIELD)
public static class Book {
    private String bookId;
    private String bookTitle;
    // ... accessors and toString 
}

и LibraryProfile

@XmlRootElement
@XmlAccessorType(XmlAccessType.FIELD)
public static class LibraryProfile {
    private String libraryId;
    private String libraryName;
    private Book newBookInfo;
    // the trick is NOT to use @XmlElementWrapper here
    private List<Book> currentBooks;
    private String foobar; // just to show a tag after the list 
    // ... accessors
}

Входные данные основаны на вашем вопросе (Я пропустил <libraryRequest>, чтобы пример был коротким)

  <libraryProfile>
    <libraryId>1</libraryId>
    <libraryName>library of alexandria</libraryName>
    <newBookInfo>
      <bookId>42</bookId>
      <bookTitle>the answer</bookTitle>
    </newBookInfo>
    <currentBooks>
      <bookId>2</bookId>
      <bookTitle>the second</bookTitle>
    </currentBooks>
    <currentBooks>
      <bookId>1</bookId>
      <bookTitle>the first</bookTitle>
    </currentBooks>
    <foobar>test-foo</foobar>
  </libraryProfile>

И вот класс тестирования:

package com.stackoverflow.answer;

import javax.xml.bind.JAXB;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.StringReader;

public class Tester {

    public static final String INPUT = "..."; // here goes your xml

    public static void main(String[] args) throws Exception {
        LibraryProfile lib = JAXB.unmarshal(new StringReader(INPUT), LibraryProfile.class);
        System.out.println(lib.getLibraryName() + " currently contains");
        System.out.println(lib.getCurrentBooks());
        System.out.println("the newest book is: " + lib.getNewBookInfo());
    }
}

Вывод теперь

library of alexandria currently contains
[Book{bookId='2', bookTitle='the second'}, Book{bookId='1', bookTitle='the first'}]
the newest book is: Book{bookId='42', bookTitle='the answer'}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...