Spring MVC - 接收 XML 对象并反序列化为集合
Spring MVC - receiving XML Objects and deserialzing into Collection
我正在尝试使用特定的标记/对象层次结构反序列化 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 元素,这就是我使用 Collection 的原因,但我无法使用 currentBooks 标签中包含的信息正确填充集合。
我能否使用 JAXB 将 XML 序列分组为 Java Collection/List,如果不能,我能否使用 Jackson 的 XML 功能将展开的 XML 标签分组到 Java 集合中?
主要目标是使用 XML 请求进入 Spring 控制器,并将 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表示classes 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>
这里是测试 class:
package com.Whosebug.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'}
我正在尝试使用特定的标记/对象层次结构反序列化 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 元素,这就是我使用 Collection 的原因,但我无法使用 currentBooks 标签中包含的信息正确填充集合。
我能否使用 JAXB 将 XML 序列分组为 Java Collection/List,如果不能,我能否使用 Jackson 的 XML 功能将展开的 XML 标签分组到 Java 集合中?
主要目标是使用 XML 请求进入 Spring 控制器,并将 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表示classes 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>
这里是测试 class:
package com.Whosebug.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'}