JAXBを使用してスキーマの拡張性を確保する方法
-
05-07-2019 - |
質問
Glassfish v2でMetro Webサービスの一部としてJAXBを使用している場合、JAXBに次の追加を指示する方法:
<xsd:any/> and <xsd:anyAttribute/>
生成された複合型にタグを付けるので、将来応答要素に要素または属性を追加するために変更を加えても、現在のクライアントは壊れません。
JAXBドキュメントにはやや欠けているようです。
解決 2
わかりました、これは私がそれを機能させた方法です:
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAnyAttribute;
import javax.xml.bind.annotation.XmlAnyElement;
import javax.xml.bind.annotation.XmlType;
import javax.xml.namespace.QName;
import org.w3c.dom.Element;
public class SchemaExtensible
{
@XmlAnyElement(lax=true)
private List<Element> otherElements;
@XmlAnyAttribute
private Map<QName,Object> otherAttributes;
}
これは、拡張したいすべての応答クラスに対してこのクラスを拡張する必要があるため、理想的ではありません(場合によっては、代わりに要求クラスから拡張できなくなります)。これら2つの方法とフィールドレベルのアノテーションを拡張してクラスレベルで追加できるようにすると、単に「適切なタグをスキーマに追加し、発生した場合はデータを破棄する」と言うことができます。甘いでしょう。
スキーマフラグメントは最終的に次のようになります。
<xs:complexType name="SchemaExtensible">
<xs:sequence>
<xs:any processContents="lax" namespace="##other" minOccurs="0" maxOccurs="unbounded"/>
</xs:sequence>
<xs:anyAttribute namespace="##other" processContents="skip"/>
</xs:complexType>
私にとって、応答オブジェクトのみにこの拡張性を許可することは、必要に応じてスキーマを少しずつ進化させることができ、多くの異なるバージョンを管理する頭痛もなく、単一の新しい属性または要素を応答オブジェクトに追加すると、既存のクライアントが破損します。
他のヒント
java.lang.Objectタイプを使用するだけです。 JAXBはデフォルトでxsd:anyを生成します。戻り値の型としてjava.lang.Objectを使用して、Webサービスメソッドからorg.w3c.dom.Nodeインスタンスを正常に返しました。私は、xsd:anyAttributeに似たようなものをイメージします-おそらくObject戻り値の型とXmlAttribute JAXBアノテーションを使用しますか?
追加: 次の注釈は、目標を達成しているように見えます。どちらもJAXB 2.0仕様の一部です。
@XmlAnyAttribute @XmlAnyElement