3

我正在使用 JAX-RS 的 Jersey 实现来创建 RESTful 服务。我希望该服务通过 JAX-RS 中内置的非常方便的 JAXB 支持同时支持 XML 和 JSON 响应。

在我尝试使用 java.util.HashMap 之前,一切都运行良好(注意:您不能将接口与 JAXB 一起使用)。我惊讶地发现 JAXB 不支持 XML 中的 Maps,尽管 Jackson JSON JAXB 插件确实支持。

第一次尝试:

@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": {
                ...
            }
        }
    ]
}   

是否有任何可能的方法可以在不破坏 JSON 输出的情况下将 HashMap 数据输出为 XML?只要所有数据都存在,我并不真正关心 XML 的特定布局是什么。对于这个问题,我更喜欢 JAXB 解决方案,但如果有一个 Jersey 配置可以解决这个问题,我会接受。

4

1 回答 1

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 的相当详尽的书。

于 2013-01-25T22:26:29.227 回答