この投稿は質問を意図していましたが、その構成中に解決策を見つけたので、それを共有したいと思います.
1 つのパラメーターのみを受け取る 1 つの操作を持つ jax-ws Web サービスがあります。それが AnimalParameter と呼ばれているとしましょう。問題は、クライアントが好きな動物で (一度に 1 つずつ) 私のサービスを呼び出すことができるということです。ただし、動物は事前定義されています。私の目的は、この「AnicmalParameter」の内容を取得し、実際には動物ごとに 1 つの操作を持つ別の Web サービス サービスを呼び出すことです。
同じ Bean を持つすべての動物をキャッチするために、XmlElements を継承と組み合わせて動的バインディングの選択肢として使用しました。
@XmlRootElement
public class AnimalParameter implements Serializable {
@XmlElements({
@XmlElement(name = "dog", type=Dog.class ),
@XmlElement(name = "cat", type=Cat.class )
})
protected Animal animal;
}
私の場合、クライアントは一度に 1 匹の動物を呼び出します。したがって、xml は次のようになります。
<animalParameter>
<dog>
...
</dog>
</animalParameter>
また :
<animalParameter>
<cat>
...
</cat>
</animalParameter>
次のようにして、動物のコンテナ全体を文字列にマーシャリングするのはかなり簡単です。
final Writer xmlString = new StringWriter();
JAXBContext jaxbContext = JAXBContext.newInstance(AnimalParameter.class);
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.marshal(animalParameter, xmlString);
ここでの問題は、受け取った動物 (パラメーター全体ではなく犬または猫) のみで xml を印刷したかったことでした。これは、コンパイル時に Web サービスが呼び出される動物がわからないため、非常に難しいようです。と。したがって、上記の Bean でさえ、リクエストを犬と猫にバインドできます。ルート要素なしで xml としてマーシャリングするにはどうすればよいでしょうか。私はビーンに便利なメソッドを入れようとしました:
@XmlRootElement
public class AnimalParameter implements Serializable
.
.
.
@XmlElement
public Animal getAnimal(){
return animal;
}
}
そして使用する:
JAXBContext jaxbContext = JAXBContext.newInstance(Animal.class);
jaxbMarshaller.marshal(animalParameter.getAnimal(), xmlString);
印刷されたxmlは次のとおりです。
<animal>...</animal> and not the desired <cat>...</cat> or <dog>...</dog>
ここでの私の理解は、xml を Java クラス/フィールドにバインドするために JAXB が使用するバインディング メタデータはどこにも格納されておらず、実行時に実行されるコードであるということです。そのため、Java フィールド「animal」には、実際にバインドされた xml ノードへの手がかりがありません。
私はこれを使用して解決しました:
String animalName = animalParameter.getAnimal().getClass().getSimpleName();
JAXBContext jaxbContext = JAXBContext.newInstance(Animal.class);
jaxbMarshaller.marshal(new JAXBElement<Operation>(new QName(animalName), Animal.class, animalParameter.getAnimal()), stringWriter);