1. ホーム

[解決済み】JAXBで@XmlRootElementが生成されない

2022-04-18 08:03:55

質問

FpML(Finanial Products Markup Language)バージョン4.5からJavaクラスを生成しようとしています。大量のコードが生成されますが、それを使うことができません。簡単な文書をシリアライズしようとすると、このようになります。

javax.xml.bind.MarshalException
  - with linked exception: [com.sun.istack.SAXException2: unable
  to marshal type
  "org.fpml._2008.fpml_4_5.PositionReport"
  as an element because it is missing an
  @XmlRootElement annotation]

実際に いいえ クラスは @XmlRootElement アノテーションを持っています。xjc (JAXB 2.1) に fpml-main-4-5.xsd を指定していますが、これにはすべての型が含まれています。

解決方法は?

他の人がすでに述べた、あるいは示唆したことをまとめると、JAXB XJC が @XmlRootElement アノテーションを生成されたクラスに付けることは、些細なことではありません ( この記事を見る ).

@XmlRootElement が存在するのは、JAXBランタイムが与えられたオブジェクトをマーシャル/アンマーシャルするために特定の情報、特にXML要素名と名前空間を必要とするからです。マーシャラーにどんな古いオブジェクトでも渡すことはできません。 @XmlRootElement はこの情報を提供する。

しかし、このアノテーションは単なる便宜的なもので、JAXBはこれを必要としません。代替案としては JAXBElement と同じ情報を提供するラッパーオブジェクトです。 @XmlRootElement しかし、アノテーションではなく、オブジェクトの形をしています。

しかし JAXBElement なぜなら、XML要素名と名前空間を知る必要があり、ビジネスロジックは通常これを知らないからです。

ありがたいことに、XJCがクラスモデルを生成するとき、そのクラスには ObjectFactory . これはJAXB v1との後方互換性のためでもありますが、XJCが生成したファクトリーメソッドを置くための場所でもあります。 JAXBElement ラッパーを作成します。XMLの名前と名前空間を処理するので、それについて心配する必要はありません。あなたはただ ObjectFactory メソッド(大規模なスキーマでは数百のメソッドがあります)を使って、必要なメソッドを探します。