Tomcat 7に展開するRestEasy 2.2.2を使用してJAX-RS Webサービスを開発しています。サービスはJAXBを使用してXMLを返します(返す必要があります)。返されたXMLは、それが次のコードで使用される方法に類似のConcurrentHashMapの表現が含まれている必要があります。RestEasyとTomcatを使用してHashMapで動作するMessageBodyWriterを取得するには?
は@XmlRootElement(name="items")
@XmlAccessorType(XmlAccessType.NONE)
public class ItemCollection
{
@XmlElement(name="item")
private ConcurrentHashMap<String, Item> items;
public ItemCollection()
{
items = new ConcurrentHashMap<String, item>();
// fill the map
}
}
Item
クラスはまた、XMLにシリアル化する必要がConcurrentHashMap
が含まれています。
これは、リソースクラスである:
@Path("/items")
public class ItemResource
{
@GET
@Produces(MediaType.APPLICATION_XML)
public ItemCollection getAllItems()
{
// get itemManager
return itemManager.getItems(); // ItemManager holds an instance of ItemCollection
}
}
このコードが実行されますが、コンテンツのないXMLを生成します。
<items>
<item/>
</items>
私は、出力のようなものであるとして取得しようとしています何:
<items>
<item id="...">
<data>...</data>
<otheritems>
<otheritem id="...">
<someotherdata>...</someotherdata>
</otheritem>
</otheritems>
</item>
<item id="...">
<data>...</data>
<otheritems>
<otheritem id="...">
<someotherdata>...</someotherdata>
</otheritem>
<otheritem id="...">
<someotherdata>...</someotherdata>
</otheritem>
<otheritem id="...">
<someotherdata>...</someotherdata>
</otheritem>
</otheritems>
</item>
</items>
MessageBodyWriter
実装が必要であることがわかりました。組み込み機能i十分ではありません。 ConcurrentHashMap
をマーシャリングするためにMessageBodyWriter
実装を試しましたが、これまでのところ動作できませんでした(つまり、コードを呼び出すことはできますが、さまざまな例外を除いて停止します)。
MessageBodyWriter
(およびMessageBodyReader
)インターフェイスをどのように実装して使用する必要があるのかよく分かりません。ビル・バークの「RESTful Java with JAX-RS」という本があります。これは、JAX-RSサービスの設計を支援するという点で非常に便利ですが、関連するセクションのMessageBodyWriter
の機能について十分な詳細を見つけることができませんでした。私のインターネット検索は正しい方向に私を導くことができるものをもたらしませんでした。
MessageBodyWriter
(およびMessageBodyReader
)のインターフェイスを正しく実装する方法を理解することができれば、嬉しいです。私は注釈が欠落しているか、誤っているのか、まったく新しいアプローチが必要かどうかは分かりません。
ご協力いただきありがとうございます。
EDIT:
次のコードを変更するには、途中でそこに私を取得します。
@XmlRootElement(name="items")
@XmlAccessorType(XmlAccessType.NONE)
public class ItemCollection
{
private ConcurrentHashMap<String, Item> items;
public ItemCollection()
{
items = new ConcurrentHashMap<String, item>();
// fill the map
}
@XmlElement(name="item")
public Collection<Item> getItems()
{
return items.values();
}
}
これは私が(サンプルは、上記の含まれている)必要があるXMLを生成します。しかし、このコードはアンマーシャリングに関しては機能しません。
java.lang.UnsupportedOperationException
java.util.AbstractCollection.add(AbstractCollection.java:221)
com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Lister.java:290)
com.sun.xml.internal.bind.v2.runtime.reflect.Lister$CollectionLister.addToPack(Lister.java:254)
com.sun.xml.internal.bind.v2.runtime.unmarshaller.Scope.add(Scope.java:106)
com.sun.xml.internal.bind.v2.runtime.property.ArrayERProperty$ReceiverImpl.receive(ArrayERProperty.java:195)
com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallingContext.endElement(UnmarshallingContext.java:507)
com.sun.xml.internal.bind.v2.runtime.unmarshaller.SAXConnector.endElement(SAXConnector.java:145)
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.endElement(AbstractSAXParser.java:601)
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanEndElement(XMLDocumentFragmentScannerImpl.java:1782)
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl$FragmentContentDriver.next(XMLDocumentFragmentScannerImpl.java:2938)
com.sun.org.apache.xerces.internal.impl.XMLDocumentScannerImpl.next(XMLDocumentScannerImpl.java:648)
com.sun.org.apache.xerces.internal.impl.XMLNSDocumentScannerImpl.next(XMLNSDocumentScannerImpl.java:140)
com.sun.org.apache.xerces.internal.impl.XMLDocumentFragmentScannerImpl.scanDocument(XMLDocumentFragmentScannerImpl.java:511)
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:808)
com.sun.org.apache.xerces.internal.parsers.XML11Configuration.parse(XML11Configuration.java:737)
com.sun.org.apache.xerces.internal.parsers.XMLParser.parse(XMLParser.java:119)
com.sun.org.apache.xerces.internal.parsers.AbstractSAXParser.parse(AbstractSAXParser.java:1205)
com.sun.org.apache.xerces.internal.jaxp.SAXParserImpl$JAXPSAXParser.parse(SAXParserImpl.java:522)
com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal0(UnmarshallerImpl.java:200)
com.sun.xml.internal.bind.v2.runtime.unmarshaller.UnmarshallerImpl.unmarshal(UnmarshallerImpl.java:173)
javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:137)
javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:142)
javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:151)
javax.xml.bind.helpers.AbstractUnmarshallerImpl.unmarshal(AbstractUnmarshallerImpl.java:169)
// ... the rest
私は理由がアンマーシャラーがCollection
にアイテムを追加しようとしないように、「適切なセッター」の欠如であると仮定しますが、私はそのセッターは次のようになりますかわからない:私は次の例外を取得します。誰かがこれを行う方法を知っていれば、私は助けていただければ幸いです。
ありがとうございます。
EDIT 2:
ところで、私は彼が@XmlJavaTypeAdapter
を使用することを提案しているクリスの回答を見てきました。私はこの提案を試してみて、必要なXMLに近いものを手に入れました。しかし、@ XmlJavaTypeAdapterを使用して取得したXMLには、余分なレベル(<items><item>
の代わりに<class><items><item>
---例のように、クラスのメンバー変数としてConcurrentHashMap
インスタンスがあります)があります。また、個々のマップアイテムの要素名を変更することもできません(これらは常に「アイテム」と呼ばれます)。
これは大きな問題ではありません。私は必要に応じて必要な変更を行い、それらと一緒に暮らすことができます。しかし、可能であれば、私は最初にそれらを持っていないようにしたいと思います。教育目的のために、EDIT 1のコードが非整列化(および可能であれば修正する方法)のために機能しない理由を理解したいと思います。
ご協力いただきありがとうございます。
この詳細な返信を書き留めていただきありがとうございます。私はそれを試して、それは私が必要なXMLの近くに私を取得します。私はアダプタを実装している間にカップルの問題にぶつかり、それらを含めるために私の投稿を編集しました。あなたがすばやく見て、何かを提案できるかどうかを知ることができたら、私は感謝します。 – alokoko