我正在尝试使用特定的标签/对象层次结构反序列化 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
我的问题是,我不知道 XML 有效负载中将包含多少个 currentBooks 标签,而且它们不包含在包装器元素中。我需要跟踪每个 currentBook 元素,这就是我使用 Collection 的原因,但我无法使用 currentBooks 标签中包含的信息正确填充集合。
我是否能够使用 JAXB 将 XML 序列分组到 Java 集合/列表中,如果不能,我是否能够使用 Jackson 的 XML 功能将未包装的 XML 标签分组到 Java 集合中?
主要目标是让 XML 请求进入 Spring Controller ,并将 XML 序列正确反序列化为 Java 列表/集合。任何建议都会有所帮助。
我正在使用 Spring Boot 1.5.8(更高版本以不同的方式给我带来麻烦),以及 Jackson 版本 2.9.5
最佳答案
这是基于 XmlElement explanation from 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'}
关于java - Spring MVC - 接收 XML 对象并反序列化为 Collection,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50495229/