【发布时间】:2016-03-15 22:59:21
【问题描述】:
我有一个 Spring Boot/MVC (v 1.3) 应用程序,它为 REST-y 类型的 Web 服务生成一些 XML。
我遇到的问题是,总的来说,结果在 ArrayList 中,因为它们是项目列表,但生成的 XML 似乎使用列表所在类的 get() 方法名称驱动各个项目的名称,而不是类名或由该类上的注释驱动的名称。
这里有一些演示代码和结果,看看我的意思:
@RestController
public class XMLTest {
@RequestMapping("/xmltest1")
public TestItem test() {
return new TestItem("testData");
}
@RequestMapping("/xmltest2")
public ArrayList<TestItem> test2() {
ArrayList<TestItem> testItems = new ArrayList<TestItem>();
testItems.add(new TestItem("testData"));
testItems.add(new TestItem("testData2"));
return testItems;
}
@RequestMapping("/xmltest3")
public TestItems test3() {
TestItems someTestItems = new TestItems();
someTestItems.setNameOfAList(new ArrayList<TestItem>());
someTestItems.getNameOfAListGetterMethod().add(new TestItem("testData"));
someTestItems.getNameOfAListGetterMethod().add(new TestItem("testData2"));
return someTestItems;
}
@JacksonXmlRootElement(localName = "testItemName")
private class TestItem {
public String itemData;
public TestItem(String itemData) {
this.itemData = itemData;
}
}
@JacksonXmlRootElement(localName = "testItemListName")
private class TestItems {
private List<TestItem> nameOfAList = null;
// This makes it not wrap the list twice, once for this class, and once for this list, which
// you put on the getter as to demo it it has the "wrong" name, which is then used for each item.
@JacksonXmlElementWrapper(useWrapping = false)
public List<TestItem> getNameOfAListGetterMethod() {
return nameOfAList;
}
public void setNameOfAList(List<TestItem> nameOfAList) {
this.nameOfAList = nameOfAList;
}
}
}
结果如下:
$ http http://localhost:9081/xmltest1
<testItemName>
<itemData>testData</itemData>
</testItemName>
$ http http://localhost:9081/xmltest2
<ArrayList>
<item>
<itemData>testData</itemData>
</item>
<item>
<itemData>testData2</itemData>
</item>
</ArrayList>
$ http http://localhost:9081/xmltest3
<testItemListName>
<nameOfAListGetterMethod>
<itemData>testData</itemData>
</nameOfAListGetterMethod>
<nameOfAListGetterMethod>
<itemData>testData2</itemData>
</nameOfAListGetterMethod>
</testItemListName>
正如您在 test3 中看到的,它使用 getter 方法的名称作为项目,总体上会反映复数(例如 getItems(),如果您获得 List 类型返回),所以您似乎必须去遵循不自然的命名约定以使其正常工作。
我希望.expect 能够做的是让实际的TestItem 节点使用@JacksonXmlRootElement(localName = "testItemName") 注释来显示它,但这似乎不可能?我想大多数人想要 a) 将数据集输出为 XML,b) 控制它的显示方式,但我找不到任何文档或确实关于它的问题。
更新
好的,我找到了答案(ish),就是添加
@JacksonXmlProperty(localName = "testItemName")
到 get() 方法。奇怪,但确实有效,并且查看源代码似乎是某种“设计”。注意这和@JacksonXmlElementWrapper(useWrapping = false) 注释一样。
【问题讨论】:
-
我不知道是否有杰克逊等价物,但在我的代码中,我将
@XmlElement(name="testItemName")和@XmlElementWrapper(name="testItemListName")注释都放在了 List 属性上。所以你可以试试这个:@JacksonXmlElement(name="testItemName") @JacksonXmlElementWrapper(name="testItemListName") private List<TestItem> nameOfAList = null; -
我根据更新找到了一个(丑陋的)解决方案,我应该把它作为答案,所以它被标记为已回答!仍然很烦人,您必须标记列表而不是仅仅解决它,但是嘿嘿。
标签: xml spring-mvc spring-boot jackson