31 JavaでのOracle XML DBアプリケーションのガイドライン
JavaでOracle XML DBアプリケーションを作成する場合の設計のガイドラインを示します。これには、Oracle XML DBのJavaサーブレットを作成および構成するためのガイドラインが含まれます。
- Oracle XML DBのJavaアプリケーションの概要
Javaコードは、JDBC用のOCIドライバを使用してクライアント・サーバーかアプリケーション・サーバーで、またはJava仮想マシン(JVM)で使用できます。 - JavaサーブレットへのアクセスまたはXMLTypeリソースへの直接アクセス
ダウンストリーム・クライアントがXMLをそのテキスト表現で処理する必要がある場合、HTTP(S)を使用してJavaサーブレットにアクセスするか、XMLType
リソースに直接アクセスする方法が最適です。この方法は、特にJavaプログラムによるXMLノード・ツリーの操作が少ない場合に有効です。 - JDBC XMLTypeサポートを使用した多数のXMLTypeオブジェクト要素へのアクセス
ダウンストリーム・クライアントが、JavaプログラムによってXMLType
インスタンスの多く、またはほとんどの要素にアクセスするアプリケーションである場合は、最適なパフォーマンスのためにJDBCXMLType
サポートを使用します。また、Javaプログラムのデバッグは、通常、データベース・サーバーの外部で行う方が簡単です。 - サーブレットを使用したデータの操作およびXMLとしての迅速な書込み
Oracle XML DBサーブレットは、エンドユーザーのためにHTMLページをフォーマットするのではなく、データベースにアクセスし、データを操作して、これをXMLとして迅速に書き込むアプリケーションに最適です。 - Oracle XML DBのJavaサーブレットのサポートの制限
Oracle XML DBプロトコル・サーバーは、FTP、HTTP 1.1、WebDAVおよびJavaサーブレットをサポートします。これは、Javaサーブレットのバージョン2.2をサポートしますが、いくつかの例外があります。 - Oracle XML DBサーブレットの構成
Oracle XML DBサーブレットは、Oracle XML DBリポジトリのxdbconfig.xml
ファイルを使用して構成されます。このファイル内の多くのXML要素は、Java 2 Enterprise Edition (J2EE)のJavaサーブレット2.2仕様部分に定義されているものと同じであり、同じセマンティクスを持ちます。 - Oracle XML DBサーブレットに対するHTTPリクエストの処理
Oracle XML DBでのHTTPリクエストの処理について説明します。 - セッション・プールおよびOracle XML DBサーブレット
Oracle Databaseは、データベース・セッションごとに1つのJava仮想マシン(VM)を使用します。セッション・プールから再利用されるセッションは、セッションが最後に使用されてからは、JVM(Java静的変数)内でどのような状態も保持します。 - ネイティブなXMLストリームのサポート
Javaノード・クラスDOM
には、Oracle固有のメソッドwrite()
があり、これによってネイティブなXMLストリームのサポートが提供されます。 - Oracle XML DBサーブレットのAPI
Oracle XML DBサーブレットでサポートされているAPIについて説明します。これらは、Javaサーブレット2.2仕様で定義されます。 - Oracle XML DBサーブレットの例
例に、ファイル・リソースの内容を出力する単純なOracle XML DBサーブレットの定義、およびそのサーブレットを登録およびマップする方法を示します。
親トピック: Oracle XML DBリポジトリ
31.1 Oracle XML DBのJavaアプリケーションの概要
Javaコードは、JDBC用のOCIドライバを使用してクライアント・サーバーかアプリケーション・サーバーで、またはJava仮想マシン(JVM)で使用できます。
データベース内のJavaは、データベース・サーバー・プロセスのコンテキストで実行されるため、Javaコードをデプロイする方法は、次のいずれかに制限されます。
-
SQLまたはPL/SQLから起動するストアド・プロシージャとしてJavaコードを実行できます。
-
Javaサーブレットを実行できます。
ストアド・プロシージャは、SQLコードおよびPL/SQLコードと簡単に統合できます。Oracle DatabaseにアクセスするプロトコルとしてOracle Net Servicesを使用する必要があります。
サーブレットは、Oracle Databaseへの最上位のエントリ・ポイントとしてより適切に機能し、Oracle DatabaseにアクセスするプロトコルとしてHTTP(S)を使用する必要があります。
すべてのOracle XML DB Application Program Interface (API) for Javaは、サーバー内とデータベース外の両方で実行するアプリケーションで使用できます。
これらのAPIには次のものが含まれます。
-
XMLType
に対するJDBCのサポート -
XMLType
クラス -
Java DOMインプリメンテーション
31.2 HTTP(S): JavaサーブレットへのアクセスまたはXMLTypeリソースへの直接アクセス
ダウンストリーム・クライアントがXMLをそのテキスト表現で処理する必要がある場合、HTTP(S)を使用してJavaサーブレットにアクセスするか、XMLType
リソースに直接アクセスする方法が最適です。この方法は、特にJavaプログラムによるXMLノード・ツリーの操作が少ない場合に有効です。
サーバーにJavaを実装すると、UCS-2 Unicode(Java文字列に必要です)で文字データを変換せずに、データをデータベースからネットワークへネイティブに移動できます。多くの場合、データはデータベースのバッファ・キャッシュからHTTP(S)接続に直接コピーされます。データをバッファ・キャッシュから、Oracle Net Servicesで使用されるSQLのシリアライズ・フォーマットに変換し、それをJDBCクライアントに移して、XMLに変換する必要はありません。データベース・サーバー内部では、XMLType
のロード・オンデマンドおよびLRUキャッシュが最も効率的です。
31.3 JDBC XMLTypeサポートを使用した多数のXMLTypeオブジェクト要素へのアクセス
ダウンストリーム・クライアントが、JavaプログラムによってXMLType
インスタンスの多く、またはほとんどの要素にアクセスするアプリケーションである場合は、最適なパフォーマンスのためにJDBC XMLType
サポートを使用します。また、Javaプログラムのデバッグは、通常、データベース・サーバーの外部で行う方が簡単です。
31.4 サーブレットを使用したデータの操作およびXMLとしての迅速な書込み
Oracle XML DBサーブレットは、エンドユーザーのためにHTMLページをフォーマットするのではなく、データベースにアクセスし、データを操作して、これをXMLとして迅速に書き込むアプリケーションに最適です。
サーブレットは、HTTP(S)を使用してアクセス可能なHTTPストアド・プロシージャをJavaで作成するためのものです。インターネット・アプリケーション全体を開発する必要がある場合は、アプリケーション・サーブレットをOracle Fusion Middlewareにデプロイし、JDBCを使用するか、またはjava.net.*
などのAPIを使用してこのサーブレットでデータベースのデータにアクセスします。
31.5 Oracle XML DBのJavaサーブレットのサポートの制限
Oracle XML DBプロトコル・サーバーは、FTP、HTTP 1.1、WebDAVおよびJavaサーブレットをサポートします。これは、Javaサーブレットのバージョン2.2をサポートしますが、いくつかの例外があります。
Javaサーブレットのバージョン2.2のサポートには、次の制限があります。
-
サーブレットのWARファイル(
web.xml
)はサポートされません。手動で操作する必要があるweb.xml
構成パラメータが存在します。たとえば、ロールの作成は、SQL CREATE ROLE
コマンドを使用して行う必要があります。 -
RequestDispatcher
および関連付けられたメソッドはサポートされません。 -
HTTPServletRequest.getCookies()
メソッドはサポートされません。 -
現在、1つの
ServletContext
(および1つのweb-app
)のみがサポートされています。 -
ステートフル・サーブレット(および
HttpSession
クラスのメソッド)は、サポートされません。サーブレットは、データベース自体の状態を保持する必要があります。
31.6 Oracle XML DBサーブレットの構成
Oracle XML DBサーブレットは、Oracle XML DBリポジトリのxdbconfig.xml
ファイルを使用して構成されます。このファイル内の多くのXML要素は、Java 2 Enterprise Edition (J2EE)のJavaサーブレット2.2仕様部分に定義されているものと同じであり、同じセマンティクスを持ちます。
表31-1に、Javaサーブレットの仕様でサーブレット・デプロイメント・ディスクリプタに対して定義されたXML要素、およびOracle XML DBがサポートする拡張要素を示します。
表31-1 サーブレット・デプロイメント・ディスクリプタに対して定義されたXML要素
XML要素名 | 定義元 | サポートの有無 | 説明 | コメント |
---|---|---|---|---|
|
Java |
なし |
アクセスに必要なHTTP認証方式を指定します。 |
該当なし |
|
Oracle |
あり |
IANAキャラクタ・セット名を指定します。 |
ISO8859、UTF-8などです。 |
|
Oracle |
あり |
ファイル名の拡張子とキャラクタ・セットの間のマッピングを指定します。 |
該当なし |
|
Java |
なし |
Webアプリケーション用のパラメータを指定します。 |
現在はサポートされていません |
|
Java |
あり |
サーブレットまたはWebアプリケーションを説明する文字列です。 |
サーブレット用にサポートされています |
|
Java |
あり |
サーブレットまたはWebアプリケーションで表示する文字列です。 |
サーブレット用にサポートされています。 |
|
Java |
なし |
すべてのインスタンスが同じJava仮想マシンで実行していない場合に、このサーブレットが機能できるかどうかを示します。 |
Oracle Databaseで実行するすべてのサーブレットは、distributableである必要があります。 |
|
Oracle |
あり |
Oracleエラー番号 |
Oracle Databaseエラー・メッセージ・リファレンスを参照してください |
|
Java |
あり |
HTTP(S)エラー・コードです。 |
RFC 2616で定義されています |
|
Java |
あり |
エラーが発生した場合のリダイレクト先のURLを定義します。 |
HTTP(S)エラー、不明なJava例外または不明なOracleエラー・メッセージで指定できます。 |
|
Java |
あり |
エラー・ページにマップされたJava例外のクラス名です。 |
該当なし |
|
Java |
あり |
MIMEタイプやキャラクタ・セットなどに関連付けるために使用するファイル名の拡張子です。 |
該当なし |
|
Oracle |
あり |
エラー・ページをマッピングするためのOracle機能コードです。 |
ORA、PLSなどです。 |
|
Java |
なし |
フォーム・ログインの試行に対するエラー・ページです。 |
現在はサポートされていません。 |
|
Java |
なし |
フォームベースのログインの構成仕様です。 |
現在はサポートされていません。 |
|
Java |
なし |
フォームベースのログイン・ページのURLです。 |
現在はサポートされていません。 |
|
Java |
あり |
サーブレットに関連付けられたアイコンのURLです。 |
サーブレット用にサポートされています。 |
|
Java |
あり |
サーブレットの初期化パラメータです。 |
該当なし |
|
Java |
なし |
サーブレットに使用するJavaServer Pagesファイルです。 |
サポートされていません |
|
Oracle |
あり |
IANA言語名です |
例: en-US |
|
Oracle |
あり |
ファイル名の拡張子と言語コンテンツの間のマッピングを指定します。 |
該当なし |
|
Java |
あり |
アイコン表示用の大きいサイズのアイコンです。 |
該当なし |
|
Java |
あり |
サーブレットの起動時にロードするかどうかを指定します。 |
該当なし |
|
Java |
あり |
エラー・ページのURLを指定します。 |
ローカル・パス名またはHTTP(S) URLを指定できます。 |
|
Java |
なし |
認証方式を指定します。 |
サポートされていません |
|
Java |
あり |
コンテンツのファイル名の拡張子とMIMEタイプの間のマッピングを指定します。 |
該当なし |
|
Java |
あり |
リソース・コンテンツのMIMEタイプ名です。 |
text/xml、application/octet-streamなどです。 |
|
Oracle |
あり |
エラー・ページに関連付けるOracleエラーを指定します。 |
該当なし |
|
Java |
あり |
サーブレットまたは |
サーブレット用にサポートされています |
|
Java |
あり |
パラメータの値です。 |
該当なし |
|
Java |
なし |
認証に使用するHTTP(S)レルムです。 |
サポートされていません |
|
Java |
あり |
特定のユーザーがサーブレットにアクセスするために必要なロールを指定します。 |
データベース・ロール名を参照します。デフォルトでは、大文字にする必要があります。 |
|
Java |
あり |
ロールのサーブレット名です。 |
データベース・ロールを呼び出すための別の名前です。サーブレットのAPIで使用します。 |
|
Java |
なし |
サーブレットが使用するロールを定義します。 |
サポートされていません。ロールは、SQLの |
|
Java |
あり |
サーブレットとロール間の参照です。 |
該当なし |
|
Java |
あり |
サーブレットの構成情報です。 |
該当なし |
|
Java |
あり |
Javaサーブレットのクラス名を指定します。 |
該当なし |
|
Oracle |
あり |
サーブレットを作成するプログラミング言語を指定します。 |
Java、C、PL/SQLのいずれかです。現在、顧客定義のサーブレットには、Javaのみがサポートされています。 |
|
Java |
あり |
サーブレットを関連付けるファイル名のパターンを指定します。 |
Javaで定義されたすべてのマッピングがサポートされています。 |
|
Java |
あり |
サーブレットの文字列名です。 |
サーブレットのAPIで使用します。 |
|
Oracle |
あり |
JavaクラスがロードされるOracleスキーマです。指定しない場合、デフォルトのリゾルバ仕様を使用してスキーマが検索されます。 |
これが指定されない場合、サーブレットを |
|
Java |
なし |
|
|
|
Java |
なし |
HTTP(S)セッションのタイムアウトです。 |
|
|
Java |
あり |
サーブレットに関連付けられた小さいアイコンです。 |
該当なし |
|
Java |
なし |
JSPタグ・ライブラリです |
JSPは現在サポートされていません。 |
|
Java |
なし |
|
JSPは現在サポートされていません。 |
|
Java |
なし |
タグ・ライブラリが格納されているWebアプリケーションのルートに相対的なパス名です。 |
JSPは現在サポートされていません。 |
|
Java |
あり |
サーブレットに関連付けられたURLパターンです。 |
Javaサーブレット2.2仕様の第10項を参照してください。 |
|
Java |
なし |
Webアプリケーションの構成です。 |
現在、1つのWebアプリケーションのみがサポートされています。 |
|
Java |
あり |
ウェルカム・ファイルの名前を指定します。 |
該当なし |
|
Java |
あり |
HTTP |
例: |
注意:
-
Javaによって
web.xml
ファイルのために定義されたパラメータ(env-entry
、env-entry-name
、env-entry-value
、env-entry-type
、ejb-ref
、ejb-ref-type
、home
、remote
、ejb-link
、resource-ref
、res-ref-name
、res-type
、res-auth
)は、J2EE準拠のEnterprise Java Beanコンテナでのみ使用でき、完全なJ2EE環境をサポートしないJavaサーブレット・コンテナには必要ありません。 -
security-constraint
、web-resource-collection
、web-resource-name
、http-method
、user-data-constraint
、transport-guarantee
およびauth-constrain
の各要素は、リソースにアクセス制御を定義するために使用されます。Oracle XML DBは、アクセス制御リスト(ACL)を使用してこの機能を提供します。ACLは、指定されたリソースへのアクセス権を持つプリンシパルを決定するアクセス制御エントリ(ACE)のリストです。web.xml
ファイルを使用したACLの生成は、今後のリリースでサポートされます。
31.7 Oracle XML DBサーブレットに対するHTTPリクエストの処理
Oracle XML DBでのHTTPリクエストの処理について説明します。
HTTPリクエストの処理は、次の手順で実行されます。
-
接続が確立されていない場合、Oracleリスナーは接続を共有サーバー・ディスパッチャに渡します。
-
新しいHTTPリクエストを受信すると、ディスパッチャは共有サーバーを起動します。
-
HTTPヘッダーは、適切な構造に解析されます。
-
共有サーバーは、Oracle XML DBセッション・プールが使用可能な場合、そこからデータベース・セッションの割当てを試行します。Oracle XML DBセッション・プールが使用できない場合、新しいセッションを作成します。
-
新しいデータベース・コールおよび新しいデータベース・トランザクションが開始されます。
-
HTTP(S)に認証ヘッダーが含まれている場合、セッションはそのデータベース・ユーザーとしてSQL*Plusにログインしている場合と同様に認証されます。認証情報が含まれず、リクエストが
GET
またはHEAD
である場合、Oracle XML DBはセッションをANONYMOUS
ユーザーとして認証しようとします。このデータベース・ユーザーのアカウントがロックされている場合、認証されないアクセスは許可されません。 -
Javaサーブレット2.2の仕様で指定されているとおり、HTTPリクエストのURLが
xdbconfig.xml
ファイルのサーブレットと一致しているかどうかが確認されます。 -
Oracle XML DBサーブレット・コンテナは、Oracle内部のJava VMで起動されます。指定したサーブレットが初期化されていない場合は、初期化されます。
-
サーブレットは、
ServletInputStream
から入力を読み取り、ServletOutputStream
に出力を書き込み、service()
メソッドから戻ります。 -
不明なOracleエラーが発生した場合、セッションはセッション・プールに戻されます。
関連トピック
31.8 セッション・プールおよびOracle XML DBサーブレット
Oracle Databaseは、データベース・セッションごとに1つのJava仮想マシン(VM)を使用します。セッション・プールから再利用されるセッションは、セッションが最後に使用されてからは、JVM(Java静的変数)内でどのような状態も保持します。
これは、メタデータなど、ユーザー固有でないJava状態をキャッシュする場合に有効ですが、保護ユーザーのデータはJava静的メモリーに格納しないでください。保護ユーザーのデータをJava静的メモリーに格納した場合、アプリケーションによってセキュリティ・ホールが出現する可能性があります。
31.9 ネイティブなXMLストリームのサポート
Javaノード・クラスDOM
には、Oracle固有のメソッドwrite()
があり、これによってネイティブなXMLストリームのサポートが提供されます。
Javaメソッドwrite()
は、次の引数を取り、void
を戻します。
-
java.io.OutputStream
ストリーム: XMLテキストの書き込み先Javaストリーム。 -
String
charEncoding
: XMLテキストを書き込むキャラクタ・エンコーディング。NULL
の場合、データベース・キャラクタ・セットが使用されます。 -
Short
indent
: ネストしたXML要素のインデントの文字数。
ストリームがデータベース内部で提供されるServletOutputStream
である場合、メソッドwrite()
には、ショートカットが実装されます。ノードのコンテンツは、出力ソケットにネイティブなコードのXMLデータで直接書き込まれます。これによって、JavaオブジェクトまたはUnicode(Java文字列に必要),との間の変換が回避され、パフォーマンスが向上します。
31.10 Oracle XML DBサーブレットのAPI
Oracle XML DBサーブレットでサポートされているAPIについて説明します。これらは、Javaサーブレット2.2仕様で定義されます。
これに対するJavadoc
は、http://download.oracle.com/javaee/1.2.1/api/index.html
で入手できます。
表31-2に、未実装のJavaサーブレット2.2のメソッドをリストします。実行時に例外が発生します。
表31-2 未実装のJavaサーブレット2.2のメソッド
インタフェース | 未実装のメソッド |
---|---|
HttpServletRequest |
|
HttpSession |
すべて |
HttpSessionBindingListener |
すべて |
31.11 Oracle XML DBサーブレットの例
例に、ファイル・リソースの内容を出力する単純なOracle XML DBサーブレットの定義、およびそのサーブレットを登録およびマップする方法を示します。
例31-1に示すサーブレットは、ファイル・リソース/public/test/foo1.text
の内容を出力します。
サーブレットをインストールするには、サーブレットをコンパイルしてからOracle Databaseにロードします。
% loadjava –grant public –u quine/curry –r test.class
最後に、例31-2に示すようにサーブレットを登録してマップし、URLと関連付けます。
例31-1 Oracle XML DBサーブレット
import javax.servlet.http.*;
import javax.servlet.*;
import java.util.*;
import java.io.*;
import java.util.*;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Reader;
import java.io.Writer;
import java.sql.DriverManager;
import java.sql.SQLException;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.OracleDriver;
import oracle.jdbc.OraclePreparedStatement;
import oracle.jdbc.OracleResultSet;
import oracle.sql.CLOB;
import oracle.xdb.XMLType;
import oracle.xdb.spi.XDBResource;
public class test extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException,
IOException {
try {
try {
// Get the database connection for the current HTTP session
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
OracleDriver ora = new OracleDriver();
OracleConnection databaseConnection =
(OracleConnection) ora.defaultConnection();
String statementText =
"SELECT XDBURIType('/public/test/foo1.txt').getClob() FROM DUAL";
OraclePreparedStatement statement =
(OraclePreparedStatement)
databaseConnection.prepareStatement(statementText);
OracleResultSet resultSet = null;
CLOB content = null;
// Execute the statement
resultSet = (OracleResultSet) statement.executeQuery();
while (resultSet.next())
{// The statement returns a CLOB.
// Copy content of CLOB to server's output stream.
content = resultSet.getCLOB(1);
Reader reader = content.getCharacterStream();
Writer writer =
new OutputStreamWriter(response.getOutputStream());
int bytesSent = 0;
int n;
char[] buffer = new char[CLOB.MAX_CHUNK_SIZE];
while (-1 != (n = reader.read(buffer)))
{ bytesSent = bytesSent + n;
writer.write(buffer, 0, n); }
writer.flush();
if (content.isOpen()) { content.close(); }}
resultSet.close();
statement.close();
databaseConnection.close();
response.getOutputStream().write('\n'); }
catch (SQLException sql)
{ throw new ServletException(sql); }}
catch (ServletException se )
{ se.printStackTrace(); }
finally
{ System.out.flush(); }}}
例31-2 Oracle XML DBサーブレットの登録およびマッピング
EXEC DBMS_XDB_CONFIG.addServlet('TestServletFoo', 'Java', 'TestServletFoo',
NULL, NULL, 'test', NULL, NULL, 'XDB');
EXEC DBMS_XDB_CONFIG.addServletMapping('/public/test/foo1.txt', 'TestServletFoo');
COMMIT;