简体   繁体   English

是否有可能JAXB(在Jersey JAX-RS中)支持XML和JSON格式的java.util.HashMap

[英]Is it possible for JAXB (in Jersey JAX-RS) to support java.util.HashMap for XML and JSON format

I am using the Jersey implementation of JAX-RS to create a RESTful service. 我正在使用JAX-RS的Jersey实现来创建RESTful服务。 I want the service to support both XML and JSON responses through the very convenient JAXB support built into JAX-RS. 我希望该服务通过JAX-RS内置的非常方便的JAXB支持来支持XML和JSON响应。

Everything works wonderfully until I attempt to use a java.util.HashMap (NOTE: you can't use interfaces with JAXB). 在尝试使用java.util.HashMap之前,一切都运行良好(注意:您不能使用JAXB接口)。 It suprised me to discover that JAXB does not have support built in for Maps in XML, although the Jackson JSON JAXB plugin does have support. 虽然Jackson JSON JAXB插件确实支持,但我发现JAXB没有为XML中的Maps内置支持,这让我感到惊讶。

First Attempt: 第一次尝试:

@XmlElement(name = "Links")
HashMap<String, LinkDTO> links = new HashMap<String, LinkDTO>();

XML Output Empty: XML输出空:

<Links />

JSON Output Correct: JSON输出正确:

"Links": {
    "status": {
        ...
    },
    "cancel": {
        ...
    }
}

So to fix the problem I figured that a custom XmlAdapter would do the trick, but that broke the JSON serialization. 因此,为了解决这个问题,我认为自定义XmlAdapter可以解决问题,但这打破了JSON序列化。

Second Attempt: 第二次尝试:

@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 Output Now Acceptable: XML输出现在可以接受:

<Links>
    <Link>
        <Key>status</Key>
        <Value> ... </Value>
    </Link>
    <Link>
        <Key>cancel</Key>
        <Value> ... </Value>
    </Link>
</Links>

JSON Output no longer a valid JavaScript Map: JSON输出不再是有效的JavaScript Map:

"Links": {
    "Link": [
        {
            "Key": "status",
            "Value": {
                ...
            }
        },
        {
            "Key": "cancel",
            "Value": {
                ...
            }
        }
    ]
}   

Is there any possible way to get the HashMap data to output as XML without breaking the JSON output? 有没有办法让HashMap数据以XML格式输出而不破坏JSON输出? I don't really care what the specific layout for the XML is as long as all of the data is present. 只要所有数据都存在,我就不在乎XML的具体布局。 I would prefer a JAXB solution to this issue, but if there is a Jersey configuration that will fix it I would settle for that. 我更喜欢这个问题的JAXB解决方案,但是如果有一个Jersey配置可以修复它,我会满足于此。

Maps seem to be a sore spot for JAXB. 地图似乎是JAXB的痛处。

However, if what you are doing is fairly simple, there is a fairly simple solution in the form of the @XmlElementWrapper annotation. 但是,如果您正在做的事情相当简单,那么@XmlElementWrapper注释的形式就有一个相当简单的解决方案。

Here is a code segment from my project: 这是我项目中的代码段:

@XmlElementWrapper(name="Parameters")
protected LinkedHashMap<String, String> parameters;

This produces XML that looks somewhat like: 这产生的XML看起来有点像:

<Parameters>
   <entry>
       <key>key-value</key>
       <value>value</value>
   </entry>
   ...
</Parameters>

I'm not sure if this works for all implementations. 我不确定这是否适用于所有实现。 I think it works with the JAXB that comes with Jersey and the JAXB reference implementation. 我认为它适用于Jersey和JAXB参考实现的JAXB。

My hope is that some future revision of the JAXB specification will have better support for Maps. 我希望JAXB规范的未来版本将更好地支持Maps。 And my hope is that someone will write/publish a fairly thorough book on JAXB. 我希望有人会在JAXB上撰写/出版一本相当全面的书。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM