我正在尝试使用特定的标记/对象层次结构反序列化XML有效负载(SOAP消息的主体,但没有别的)。尝试将未包装的对象聚合到List中时,会抛出MismatchedInputException。
示例有效负载
int
Java对象
<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>
我的问题是我不知道XML有效负载中会有多少个currentBooks标签,并且它们不会包含在包装元素中。我需要跟踪每个currentBook元素,这就是我使用Collection的原因,但我无法使用currentBooks标记中包含的信息正确填充集合。
我是否可以使用JAXB将XML序列分组为Java Collection / List,如果没有,我是否可以使用Jackson的XML功能将未打包的XML标记分组到Java Collection中?
主要目标是使用XML请求进入Spring Controller并将XML序列正确地反序列化为Java List / Collection。任何建议都会有帮助。
我正在使用Spring Boot 1.5.8(后来的版本以不同的方式给我带来麻烦),而Jackson版本为2.9.5
答案 0 :(得分:2)
这基于XmlElement explanation from actimem.com。
机械师解释说:
- 仅当字段名称不等于xml标记名称时才需要@XmlElement
。
- 如果您想将字段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'}