我正在使用JAX-RS的Jersey实现来创建RESTful服务。我希望该服务通过JAX-RS内置的非常方便的JAXB支持来支持XML和JSON响应。
在尝试使用java.util.HashMap之前,一切都运行良好(注意:您不能使用JAXB接口)。虽然Jackson JSON JAXB插件确实有支持,但我发现JAXB没有为Maps in XML内置支持,这让我很惊讶。
首次尝试:
@XmlElement(name = "Links")
HashMap<String, LinkDTO> links = new HashMap<String, LinkDTO>();
XML输出为空:
<Links />
JSON输出正确:
"Links": {
"status": {
...
},
"cancel": {
...
}
}
因此,为了解决这个问题,我认为自定义XmlAdapter可以解决这个问题,但这打破了JSON序列化。
第二次尝试:
@XmlJavaTypeAdapter(HashMapAdapter.class)
@XmlElement(name = "Links")
HashMap<String, LinkDTO> links = new HashMap<String, LinkDTO>();
public class HashMapAdapter extends XmlAdapter<MapElement, HashMap<String, LinkDTO>> {
public HashMap<String, LinkDTO> unmarshal(ArrayList<MapEntryType> jaxbDTO) throws Exception {
... mapping code ...
}
public MapElement marshal(HashMap<String, LinkDTO> map) throws Exception {
... mapping code ...
}
}
public static class MapElement {
@XmlElement(name = "Link")
public List<MapEntryType> entries = new ArrayList<MapEntryType>();
}
public class MapEntryType {
@XmlElement(name = "Key")
public String key;
@XmlElement(name = "Value")
public RESTfulLinkDTO value;
}
现在可以接受XML输出:
<Links>
<Link>
<Key>status</Key>
<Value> ... </Value>
</Link>
<Link>
<Key>cancel</Key>
<Value> ... </Value>
</Link>
</Links>
JSON输出不再是有效的JavaScript地图:
"Links": {
"Link": [
{
"Key": "status",
"Value": {
...
}
},
{
"Key": "cancel",
"Value": {
...
}
}
]
}
有没有办法让HashMap数据以XML格式输出而不破坏JSON输出?只要所有数据都存在,我就不在乎XML的具体布局。我更喜欢这个问题的JAXB解决方案,但是如果有一个Jersey配置可以解决它,我会满足于此。
答案 0 :(得分:1)
地图似乎是JAXB的痛处。
但是,如果您正在做的事情非常简单,那么@XmlElementWrapper注释的形式就有一个相当简单的解决方案。
以下是我项目的代码段:
@XmlElementWrapper(name="Parameters")
protected LinkedHashMap<String, String> parameters;
这会产生类似于:
的XML<Parameters>
<entry>
<key>key-value</key>
<value>value</value>
</entry>
...
</Parameters>
我不确定这是否适用于所有实现。我认为它适用于Jersey和JAXB参考实现的JAXB。
我希望JAXB规范的未来版本将更好地支持Maps。我希望有人会在JAXB上撰写/出版一本相当全面的书。