3

JAX-RS の Jersey 実装を使用して RESTful サービスを作成しています。JAX-RS に組み込まれた非常に便利な JAXB サポートを通じて、サービスが XML と JSON の両方の応答をサポートすることを望んでいます。

java.util.HashMap を使用しようとするまで、すべてがうまく機能します (注: JAXB でインターフェイスを使用することはできません)。Jackson JSON JAXB プラグインにはサポートがありますが、JAXB には XML のマップのサポートが組み込まれていないことを発見して驚きました。

最初の試み:

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

XML 出力が空です:

<Links />

JSON 出力が正しい:

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

そのため、問題を解決するために、カスタム XmlAdapter でうまくいくと考えましたが、JSON シリアル化が壊れてしまいました。

2 回目の試行:

@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>

これがすべての実装で機能するかどうかはわかりません。ジャージーに付属しているJAXBとJAXBリファレンス実装で動作すると思います。

私の希望は、JAXB仕様の将来の改訂により、マップのサポートが改善されることです。そして、誰かがJAXBに関するかなり徹底的な本を書いたり出版したりすることを願っています。

于 2013-01-25T22:26:29.227 に答える