JavaでOracle XML DBアプリケーションを作成する場合の設計のガイドラインを示します。これには、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インプリメンテーション
ダウンストリーム・クライアントがXMLをそのテキスト表現で処理する必要がある場合、HTTP(S)を使用してJavaサーブレットにアクセスするか、XMLType
リソースに直接アクセスする方法が最適です。この方法は、特にJavaプログラムによるXMLノード・ツリーの操作が少ない場合に有効です。
サーバーにJavaを実装すると、UCS-2 Unicode(Java文字列に必要です)で文字データを変換せずに、データをデータベースからネットワークへネイティブに移動できます。多くの場合、データはデータベースのバッファ・キャッシュからHTTP(S)接続に直接コピーされます。データをバッファ・キャッシュから、Oracle Net Servicesで使用されるSQLのシリアライズ・フォーマットに変換し、それをJDBCクライアントに移して、XMLに変換する必要はありません。データベース・サーバー内部では、XMLType
のロード・オンデマンドおよびLRUキャッシュが最も効率的です。
ダウンストリーム・クライアントが、JavaプログラムによってXMLType
インスタンスの多く、またはほとんどの要素にアクセスするアプリケーションである場合は、最適なパフォーマンスのためにJDBC XMLType
サポートを使用します。また、Javaプログラムのデバッグは、通常、データベース・サーバーの外部で行う方が簡単です。
Oracle XML DBサーブレットは、エンドユーザーのためにHTMLページをフォーマットするのではなく、データベースにアクセスし、データを操作して、これをXMLとして迅速に書き込むアプリケーションに最適です。
サーブレットは、HTTP(S)を使用してアクセス可能なHTTPストアド・プロシージャをJavaで作成するためのものです。インターネット・アプリケーション全体を開発する必要がある場合は、アプリケーション・サーブレットをOracle Fusion Middlewareにデプロイし、JDBCを使用するか、またはjava.net.*
などのAPIを使用してこのサーブレットでデータベースのデータにアクセスします。
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
クラスのメソッド)は、サポートされません。サーブレットは、データベース自体の状態を保持する必要があります。
Oracle XML DBサーブレットは、Oracle XML DBリポジトリのxdbconfig.xml
ファイルを使用して構成されます。このファイル内の多くのXML要素は、Java 2 Enterprise Edition (J2EE)のJavaサーブレット2.2仕様部分に定義されているものと同じであり、同じセマンティクスを持ちます。
表32-1に、Javaサーブレットの仕様でサーブレット・デプロイメント・ディスクリプタに対して定義されたXML要素、およびOracle XML DBがサポートする拡張要素を示します。
表32-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の生成は、今後のリリースでサポートされます。
関連項目:
xdbconfig.xml
ファイルの構成の詳細は、 Oracle XML DBの管理を参照してください。
Oracle XML DBでの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エラーが発生した場合、セッションはセッション・プールに戻されます。
関連項目:
Oracle Databaseは、データベース・セッションごとに1つのJava仮想マシン(VM)を使用します。セッション・プールから再利用されるセッションは、セッションが最後に使用されてからは、JVM(Java静的変数)内でどのような状態も保持します。
これは、メタデータなど、ユーザー固有でないJava状態をキャッシュする場合に有効ですが、保護ユーザーのデータはJava静的メモリーに格納しないでください。保護ユーザーのデータをJava静的メモリーに格納した場合、アプリケーションによってセキュリティ・ホールが出現する可能性があります。
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文字列に必要),との間の変換が回避され、パフォーマンスが向上します。
Oracle XML DBサーブレットでサポートされているAPIについて説明します。これらは、Javaサーブレット2.2仕様で定義されます。
これに対するJavadoc
は、http://download.oracle.com/javaee/1.2.1/api/index.html
で入手できます。
表32-2に、未実装のJavaサーブレット2.2メソッドをリストします。実行時に例外が発生します。
表32-2 未実装のJavaサーブレット2.2メソッド
インタフェース | 未実装のメソッド |
---|---|
HttpServletRequest |
|
HttpSession |
all |
HttpSessionBindingListener |
all |
例に、ファイル・リソースの内容を出力する単純なOracle XML DBサーブレットの定義、およびそのサーブレットを登録およびマップする方法を示します。
例32-1に示すサーブレットは、ファイル・リソース/public/test/foo1.text
の内容を出力します。
サーブレットをインストールするには、サーブレットをコンパイルしてからOracle Databaseにロードします。
% loadjava –grant public –u quine/curry –r test.class
最後に、例32-2に示すようにサーブレットを登録してマップし、URLと関連付けます。
例32-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(); }}}
例32-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;