web-dev-qa-db-ja.com

JAXB 2のObjectFactoryクラスのポイントは何ですか?

私はJAXBを初めて使用し、JAXB 2.1.3のxjcを使用してXMLスキーマからクラスのセットを生成しました。スキーマ内の各要素のクラスを生成することに加えて、ObjectFactoryクラスを作成しました。

要素を直接インスタンス化するのを妨げるものはないようです。

MyElement element = new MyElement();

チュートリアルは好むようです

MyElement element = new ObjectFactory().createMyElement();

ObjectFactory.Javaを調べると、次のことがわかります。

public MyElement createMyElement() {
    return new MyElement();
}

それで取引は何ですか?なぜObjectFactoryクラスを保持する必要がありますか?変更されたスキーマから再コンパイルする場合にも上書きされると思います。

95
Andrew Coleson

下位互換性だけが理由ではありません。 :-P

要素のコンテンツが取り得る値に複雑な制約があるスキーマなど、より複雑なスキーマでは、実際のJAXBElementオブジェクトを作成する必要がある場合があります。通常、手作業で作成するのは簡単なことではないため、create*メソッドは大変な作業を行います。例(XHTML 1.1スキーマから):

@XmlElementDecl(namespace = "http://www.w3.org/1999/xhtml", name = "style", scope = XhtmlHeadType.class)
public JAXBElement<XhtmlStyleType> createXhtmlHeadTypeStyle(XhtmlStyleType value) {
    return new JAXBElement<XhtmlStyleType>(_XhtmlHeadTypeStyle_QNAME, XhtmlStyleType.class, XhtmlHeadType.class, value);
}

<style>タグを<head>タグに取得する方法は次のとおりです。

ObjectFactory factory = new ObjectFactory();
XhtmlHtmlType html = factory.createXhtmlHtmlType();
XhtmlHeadType head = factory.createXhtmlHeadType();
html.setHead(head);
XhtmlStyleType style = factory.createXhtmlStyleType();
head.getContent().add(factory.createXhtmlHeadTypeStyle(style));

ObjectFactoryの最初の3つの使用法は(一貫性には役立ちますが)不要であると考えられますが、4つ目の方法はJAXBをはるかに使いやすくします。毎回new JAXBElementを手書きで書かなければならないイメージング!

66

@Chrisが指摘したように、JAXBはPOJOで動作できないことがあります。スキーマをJavaに正確にマッピングできないためです。これらの場合、追加の型情報を提供するには、JAXBElementラッパーオブジェクトが必要です。

これが一般的であるところに出くわした2つの具体的な例があります。

  • @XmlRootElement注釈を持たないクラスのオブジェクトをマーシャリングする場合。デフォルトでは、XJCは一部の要素に対してのみ@XmlRootElementを生成し、他の要素に対しては生成しません。これの正確なロジックは少し複雑ですが、XJCに "simple binding mode" を使用して@XmlRootElementクラスをさらに生成させることができます。

  • スキーマが置換グループを使用する場合。これはかなり高度なスキーマの使用方法ですが、XJCはJAXBElementラッパーを多用することにより、置換グループをJavaに変換します。

(何らかの理由で)JAXBElementを多用するXJCで生成されたオブジェクトモデルでは、それらのJAXBElementインスタンスを構築する方法が必要です。生成されたObjectFactoryは、最も簡単な方法です。あなたはcan自分でそれらを構築できますが、そうするのは不格好でエラーが発生しやすいです。

38
skaffman

下位互換性、私は推測する...

http://weblogs.Java.net/blog/kohsuke/archive/2005/08/a_story_of_migr.html

...もうObjectFactory.createXYZはありません。これらのファクトリメソッドの問題は、チェックされたJAXBExceptionをスローすることでした。これで、try/catchブロックを使用せずに、新しいXYZ()を実行できます。 (私は知っている、知っている、...これはそれらの「私たちは何を考えていたのか!?」事の一つです)...

9
Bert F