はじめに
前回は、XMLDBアプリケーション開発の設計編として、サンプルアプリケーションの仕様とアプリケーション全体の設計方針、Cyber Luxeonでアプリケーションを開発する際に前提知識となるCyber Luxeonの接続形態、トランザクションなどについて説明しました。
実装編の前段階となる本稿では、サンプルアプリケーションで主に使用するJava APIのチュートリアル編として、JAXB API(クラス・アノテーション)とCyber Luxeon Java APIについて説明します。次回、実装編では、本稿で説明したAPIを実際に用いて、XMLDBのCRUD(生成・抽出・更新・削除)処理を中心としたサンプルアプリケーションを実装していきます。
対象読者
XMLに触れたことがある方、RDBなどデータベースを操作したことがある方、Javaでプログラミングしたことがある方を対象とします。
必要な環境
- OS::Windows XP
- DB:Cyber Luxeon ver2.0 Developer Edition
- Java SE 6
- Tomcat 6.0.10
JAXB
JAXBの概要
JAXBは、XMLデータとJavaオブジェクトの相互変換を実現するためのAPIで、Java SE 6から標準API(パッケージ名はjavax.xml.bind.*)となりました。JAXBのアーキテクチャの全体像につきましては、前回(Cyber Luxeonで学ぶXMLDB入門 第4回)を参照してください。
主要クラス
まずは、JAXBの主要機能となるJavaオブジェクトからXMLへの変換、そしてXMLからJavaオブジェクトへの変換で使用する主なクラス(インターフェイス)を以下の表に示します。
クラス名 | 説明 |
JAXBContext | JAXB APIへのエントリポイントを提供する |
Marshaller | JavaオブジェクトをXMLデータに変換する |
Unmarshaller | XMLデータをJavaオブジェクトに変換する |
Marshalとは「整列化する」といった意味で、MarshallerはJavaオブジェクトをXML文字列へ整列化します。Unmarshallerはその逆で、XMLの文字列として整列化されたものをJavaオブジェクトに戻す役割を持ちます。
Javaオブジェクト→XML変換
それでは、まずJavaオブジェクトからXMLに変換する場合を説明します。
サンプルソース
以下はJavaオブジェクトからXMLに変換する際のソース例です。
// JAXBContextの取得 JAXBContext context = JAXBContext.newInstance( obj.getClass() ); // Marshallerの生成 Marshaller marshaller = context.createMarshaller(); // Marshallerのプロパティを設定 marshaller.setProperty( Marshaller.JAXB_ENCODING, "UTF-8" ); marshaller.setProperty( Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.FALSE ); // Javaオブジェクト→XML変換処理 OutputStream outputStream = new FileOutputStream( "item.xml" ); marshaller.marshal( obj , outputStream ); // Javaオブジェクト→XML
Marshallerの生成・プロパティ設定
JAXBContextのcreateMarshaller
メソッドを使用して生成します。Marshallerにはいくつかプロパティが定義されており、getProperty
、setProperty
メソッドを通じてアクセスすることができます。以下の表に、Marshallerのプロパティをまとめました。
プロパティ名 | 説明 |
JAXB_ENCODING | 整列化されたXMLデータの出力エンコーディングを指定する |
JAXB_FORMATTED_OUTPUT | 整列化されたXMLデータを改行とインデントを使用して書式設定するかどうかを指定する |
JAXB_FRAGMENT | marshallerが文書レベルのイベント(startDocumentまたはendDocumentの呼び出し)を生成するかどうかを指定する |
JAXB_NO_NAMESPACE_SCHEMA_LOCATION | 整列化されたXML出力に設定するxsi:noNamespaceSchemaLocation属性値を指定する |
JAXB_SCHEMA_LOCATION | 整列化されたXML出力に設定するxsi:schemaLocation属性値を指定する |
marshal処理
上記ソースのmarshaller.marshal
が、実際にJavaオブジェクトからXMLに変換する処理です。marshal
メソッドの第1引数には変換元のJavaオブジェクトを指定し、第2引数にはXML変換後出力先を指定します。第2引数にはサンプルソースのようなOutputStreamだけではなく、以下の表に示したさまざまな引数を指定することができます。
クラス | 説明 |
org.xml.sax.ContentHandler | SAX2イベントハンドラ |
org.w3c.dom.Node | DOMツリー上のノード |
java.io.OutputStream | 出力バイナリ配列 |
javax.xml.transform.Result | XSLTの変換結果 |
javax.io.Writer | 文字出力ストリーム |
javax.xml.stream.XMLEventWriter | StAX(下コラム参照)でXML文書を書き込むための最上位のインターフェイス |
javax.xml.stream.XMLStreamWriter | StAX(下コラム参照)でXMLの書き込み方法を指定するインターフェイス |
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オブジェクトに変換する際のソース例です。
// JAXBContextの取得 JAXBContext jc = JAXBContext.newInstance( "sample.entity.Item" ); // 引数には変換先オブジェクトのクラス名を指定 // Unmarshallerの生成 Unmarshaller unmarshaller = jc.createUnmarshaller(); // XML変換処理→Javaオブジェクト Object obj = unmarshaller.unmarshal( new File( "item.xml" ) );
Unmarshallerの生成
JAXBContextのcreateUnmarshaller
メソッドを使用して生成します。なおUnmarshallerでは、MarshallerのようにAPIにプロパティは定義されていませんが、getProperty
、setProperty
メソッドを通じて、Unmarshallerインターフェイスの実装クラス独自のプロパティにアクセスすることはできます。
unmarshal処理
unmarshaller.unmarshal
の箇所が、実際にXMLからJavaオブジェクトに変換する処理です。unmarshal
メソッドは引数を1つしか持ちません。第1引数には、XML形式のデータを指定します。unmarshal
メソッドの第1引数に指定できるクラス(インターフェイス)を以下の表にまとめました。
クラス | 説明 |
java.io.File | XMLファイル |
org.xml.sax.InputSource | SAXの入力ソース |
java.io.InputStream | 文字入力ストリーム |
org.w3c.dom.Node | DOMツリー上のノード |
java.io.Reader | 文字入力ストリーム |
javax.xml.transform.Source | XSLTの変換元ソース |
javax.xml.stream.XMLEventReader | StAXでXMLEventを構文解析するための最上位のインターフェイス |
javax.xml.stream.XMLStreamReader | StAXでXMLを読み込むための文字入力ストリーム |