mb_language("uni"); mb_internal_encoding("utf-8"); mb_http_input("auto"); mb_http_output("utf-8"); ?>
WINGSプロジェクト 佐藤 治夫 (株式会社ビープラウド) [著], 山田 祥寛 [監修]
出典:開発者のための実装Webマガジン「Codezine」(株式会社翔泳社)
Cyber LuxeonとJavaアプリケーションが連携する方法について、簡単なWebアプリケーションのサンプルを用いて説明します。今回は実装編の前段階として、サンプルアプリケーションで主に使用するJAXB API、Cyber Luxeon Java APIについて説明します。
はじめに
前回は、 XML DBアプリケーション開発の設計編として、サンプルアプリケーションの仕様とアプリケーション全体の設計方針、Cyber Luxeonでアプリケーションを開発する際に前提知識となるCyber Luxeonの接続形態、トランザクションなどについて説明しました。
実装編の前段階となる本稿では、サンプルアプリケーションで主に使用するJava APIのチュートリアル編として、JAXB API(クラス・アノテーション)とCyber Luxeon Java APIについて説明します。次回、実装編では、本稿で説明したAPIを実際に用いて、XML DBのCRUD(生成・抽出・更新・削除)処理を中心としたサンプルアプリケーションを実装していきます。
対象読者
XMLに触れたことがある方、RDBなどデータベースを操作したことがある方、Javaでプログラミングしたことがある方を対象とします。
必要な環境
JAXB
JAXBの概要
JAXBは、XMLデータとJavaオブジェクトの相互変換を実現するためのAPIで、Java SE 6から標準API(パッケージ名はjavax.xml.bind.*)となりました。JAXBのアーキテクチャの全体像につきましては、前回(Cyber Luxeonで学ぶXML DB入門 第4回)を参照してください。
主要クラス
まずは、JAXBの主要機能となるJavaオブジェクトからXMLへの変換、そしてXMLからJavaオブジェクトへの変換で使用する主なクラス(インターフェイス)を以下の表に示します。
Marshalとは「整列化する」といった意味で、MarshallerはJavaオブジェクトをXML文字列へ整列化します。Unmarshallerはその逆で、XMLの文字列として整列化されたものをJavaオブジェクトに戻す役割を持ちます。
Javaオブジェクト→XML変換
それでは、まずJavaオブジェクトからXMLに変換する場合を説明します。
サンプルソース
以下はJavaオブジェクトからXMLに変換する際のソース例です。
Marshallerの生成・プロパティ設定
JAXBContextのcreateMarshallerメソッドを使用して生成します。Marshallerにはいくつかプロパティが定義されており、getProperty、setPropertyメソッドを通じてアクセスすることができます。以下の表に、Marshallerのプロパティをまとめました。
marshal処理
上記ソースのmarshaller.marshalが、実際にJavaオブジェクトからXMLに変換する処理です。marshalメソッドの第1引数には変換元のJavaオブジェクトを指定し、第2引数にはXML変換後出力先を指定します。第2引数にはサンプルソースのようなOutputStreamだけではなく、以下の表に示したさまざまな引数を指定することができます。
StAXの概要
StAX(Streaming API for XML)は、DOM、SAXに続くXML文書を読み書きするためのAPIとして、JSR173で標準化され、Java SE 6で標準APIとなりました(パッケージ名はjavax.xml.stream.*)。
XMLを処理するためのAPIとして、XMLが誕生して間もない頃からDOMとSAXが主に使用されてきました。DOMはXMLドキュメント全体をメモリ上に持つことで、文書へのランダムアクセスが可能となるというメリットがある一方、文書全体をメモリに持つので、メモリを大量に消費しがちというデメリットを持っています。それに対し、SAXは文書を1回だけスキャンし、XMLエンティティ出現イベントの発生ごとにパーサからイベントを受け取るという(push型)コールバック形式の処理形式を特徴としています。この処理形式は、使用メモリが少なく、より高速に動作する場合が多いというメリットに対し、アプリケーション側でランダムにXMLにアクセスすることができないため、イベント間の処理制御が必要な場合にプログラミングが複雑になる傾向があるというデメリットを持っていました。
StAXは、DOMとSAXの中間の手法として設計されました。StAXでは、プログラムの操作点は文書内のある地点を指すカーソルです。StAXは、アプリケーション側でランダムにカーソルを進め、情報を取得することができるというメリットを持っています(pull型)。加えてStAXは、XML文書すべてを一度に読み込まないので、メモリーの使用量も少なくすることができるというメリットも実現しています。
このようにStAXはDOMとSAXの特長を併せ持ったAPIなので、XMLアプリケーションの開発に大きなメリットをもたらす技術と言えるでしょう。 |
XML変換→Javaオブジェクト変換
では、次にXMLからJavaオブジェクトに変換する場合について説明します。
サンプルソース
以下はXMLからJavaオブジェクトに変換する際のソース例です。
Unmarshallerの生成
JAXBContextのcreateUnmarshallerメソッドを使用して生成します。なおUnmarshallerでは、MarshallerのようにAPIにプロパティは定義されていませんが、getProperty、setPropertyメソッドを通じて、Unmarshallerインターフェイスの実装クラス独自のプロパティにアクセスすることはできます。
unmarshal処理
unmarshaller.unmarshalの箇所が、実際にXMLからJavaオブジェクトに変換する処理です。unmarshalメソッドは引数を1つしか持ちません。第1引数には、XML形式のデータを指定します。unmarshalメソッドの第1引数に指定できるクラス(インターフェイス)を以下の表にまとめました。
JAXBアノテーション
JAXBの主要クラスの説明に続いてJAXB 2.0から追加されたJAXBアノテーションについて説明します。JAXB 2.0以前は、JAXBを用いたアプリケーションの開発過程の中で、XMLの構造を定義したXMLSchemaファイルを必ず作成する必要があり、敷居がやや高いというデメリットがありました。しかしJAXB 2.0からは、JAXBアノテーションをJavaクラスに定義することで、JavaクラスとXMLの関連付けが容易に可能になり、XMLSchemaファイルの作成も必須ではなくなりました。ここではjavax.xml.bind.annotationパッケージに定義されている32のアノテーションのうち、最も頻繁に使用するであろうアノテーション(XmlRootElement、XmlType、XmlElement、XmlAttribute)について説明します。
JavaクラスとXMLルート要素の関連付け(XmlRootElement)
JavaトップクラスとXMLのルート要素を関連付けるには、@XmlRootElementを使用します。クラス名とXMLのルート要素の名前が異なる場合は、@XmlRootElementのname属性にXMLのルート要素名を指定します。以下に@XmlRootElementを定義したソースを示します。
@XmlRootElementで定義したルート要素は、XMLSchemaのxs:element(ルート要素)に対応します。以下に上記Javaソースに対応するXMLSchemaの定義を示します。
要素並び順の定義(XmlType)
XML要素の並び順を定義するには、@XmlTypeを使用します。@XmlTypeはXMLSchemaの「xs:complexType(複合型)」とマッピングします。@XmlTypeは、@XmlRootElem、@XmlAccessorOrder、@XmlAccessorType、@XmlEnumのアノテーションとセットで使用することができます。
以下がXmlRootElementとXmlTypeを使用して要素の並び順を定義したサンプルソースです。
@XmlTypeで定義する並び順は、XMLSchemaのxs:sequenceに対応します。以下に上記Javaソースに対応するXMLSchemaの定義を示します。
Javaクラスのインスタンス変数とXML要素の関連付け(XmlElement)
Javaクラスのインスタンス変数とXMLの要素を関連付けるには、@XmlElementを使用します。@XmlTypeはXMLSchemaの「xs:element」とマッピングします。Javaクラスのインスタンス変数名とXMLの要素名が異なる場合には、name属性を使用することによって関連付けることができます。また、インスタンス変数の型によって、マッピングされるXML要素の型も決定されます。例えば、インスタンス変数の型がStringの場合は、xs:string、intの場合はxs:int、java.util.Dateの場合はxs:dateTimeにそれぞれマッピングされます。
@XmlElementの定義は、XMLSchemaのxs:elementに対応しますが、アノテーションの丸カッコ内に属性を定義することによってxs:elementの属性値を明示的に設定することができます。以下の表に@XmlElementの属性とxs:elementの属性の対応、省略時のデフォルト値をまとめました。
以下に上記Javaソースに対応するXMLSchemaの定義を示します。
@XmlAttributeの定義は、XMLSchemaのxs:attributeに対応しますが、アノテーションの丸カッコ内に属性を定義することによってxs:attributeの属性値を明示的に設定することができます。以下の表に@XmlAttributeの属性とxs:attributeの属性の対応をまとめました。
以下に上記Javaソースに対応するXMLSchemaの定義を示します。
XMLのラッパー要素定義
XMLのラッパー要素とは、XML要素をひとくくりにするために使用される要素です。主に同じ要素が繰り返される場合に、その繰り返し要素をある親要素で囲むような場合に使用されます。Javaクラスの属性にラップされる要素(サンプルではoption)の@XmlElementの記述とセットで@XmlElementWrapper(サンプルで対応する要素はoptions)を指定します。繰り返しの要素は、Javaクラス上では配列やListなどで表現されます。
@XmlElementWrapperの定義は、XMLSchemaのxs:elementとxs:complexTypeの組み合わせに対応します。以下に上記Javaソースに対応するXMLSchemaの定義を示します。
また、上記XMLSchemaのXML要素の例を以下に示します。option要素がoptions要素で囲まれています。
XMLスキーマファイルの出力
JDK 6に標準で付属しているschemagenというツールを使用して、XMLスキーマファイルを出力することができます。なお、スキーマファイルを使用しなくても、サンプルアプリケーションは実行できます。アプリケーション内でXMLバリデーションを実行する場合は、schemagenで生成したファイルを使用すると良いでしょう。
schemagenは以下の方法で実行します。
カレントフォルダにファイルが作成されると、以下のメッセージが出力されます。
schemagenで出力したXMLSchemaファイルの例については次回、サンプルアプリケーションのクラス定義に基づいて作成されたファイルを掲載します。
■著者紹介■ |
WINGSプロジェクト 佐藤 治夫 (株式会社ビープラウド) (サトウ ハルオ) <WINGSプロジェクトについて>
有限会社 WINGSプロジェクトが運営する、テクニカルライティング・プロジェクト。海外記事の翻訳から、主にサーバサイド分野の書籍・雑誌/Web記事の執筆、講演、アプリケーション開発等を幅広く手がける。2005年9月時点での登録メンバは20名で、現在も一緒に執筆をできる有志を募集中。執筆に興味のある方は、どしどし応募頂きたい。CodeZine記事は、WINGSプロジェクト執筆/山田祥寛監修で今後も続々公開予定。
静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「入門シリーズ(サーバサイドAjax/XML DB/PEAR/Smarty)」「独習シリーズ(ASP.NET/PHP)」「10日でおぼえる入門教室シリーズ(ASP.NET/PHP/Jakarta/JSP&サーブレット/XML)」「Pocket詳解辞典シリーズ(ASP.NET/PHP/Perl&CGI)」「今日からつかえるシリーズ(PHP/JSP&サーブレット/XML/ASP)」「書き込み式 SQLのドリル」他、著書多数。 |
▲このページのTOPへ