ヘッダーをスキップ
Oracle® XML DB開発者ガイド
11gリリース2 (11.2)
B70200-03
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

32 JavaでのOracle XML DBアプリケーションの作成

この章では、Oracle XML DBアプリケーションをJavaで作成する方法を説明します。サーブレットを含むJavaアプリケーションを作成する場合の設計のガイドライン、およびOracle XML DBサーブレットを構成する方法を説明します。

この章の内容は次のとおりです。

Oracle XML DBのJavaアプリケーションの概要

Javaコードは次の方法で使用できます。

  • データベースでのJava仮想マシン(JVM)の使用。

  • クライアント・サーバーまたはアプリケーション・サーバーでのJDBC用のOCIドライバの使用。

データベース内のJavaは、データベース・サーバー・プロセスのコンテキストで実行されるため、Javaコードをデプロイする方法は、次のいずれかに制限されます。

  • SQLまたはPL/SQLから起動するストアド・プロシージャとしてJavaコードを実行できます。

  • Javaサーブレットを実行できます。

ストアド・プロシージャは、SQLコードおよびPL/SQLコードと簡単に統合できます。Oracle DatabaseにアクセスするプロトコルとしてOracle Net Servicesを使用する必要があります。

サーブレットは、Oracle Databaseへの最上位のエントリ・ポイントとしてより適切に機能し、Oracle DatabaseにアクセスするプロトコルとしてHTTP(S)を使用する必要があります。

データベース内外で使用可能なOracle XML DB API

すべてのOracle XML DB APIは、サーバー内とデータベース外の両方で実行するアプリケーションで使用可能です。次のものが含まれます。

  • XMLTypeに対するJDBCのサポート

  • XMLTypeクラス

  • Java DOMインプリメンテーション

設計のガイドライン: データベース内外でのJava

JavaでOracle XML DBアプリケーションを作成するアーキテクチャを選択する場合は、次のガイドラインを考慮します。

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キャッシュが最も効率的です。

多くのXMLTypeオブジェクト要素へのアクセス: JDBC XMLTypeサポートの使用

ダウンストリーム・クライアントが、JavaプログラムによってXMLTypeインスタンスの多く、またはほとんどの要素にアクセスするアプリケーションである場合は、最適のパフォーマンスのためJDBC XMLTypeサポートを使用します。また、Javaプログラムのデバッグは、通常、データベース・サーバーの外部で行う方が簡単です。

サーブレットを使用したデータの操作およびXMLとしての迅速な書込み

Oracle XML DBサーブレットは、HTTP(S)を使用してアクセス可能なHTTPストアド・プロシージャをJavaで作成するためのものです。インターネット・アプリケーション全体を開発することを目的としたプラットフォームではありません。その場合、Oracle Application Serverのアプリケーション・サーバーにアプリケーション・サーブレットをデプロイし、JDBCを使用するか、またはjava.net.*や同様のAPIを使用してデータベース内のデータにアクセスし、HTTP(S)を使用してXMLデータを取得する必要があります。

サーブレットは、エンドユーザーのためにHTMLページをフォーマットするのではなく、データベースにアクセスし、データを操作して、そのデータをXMLとして迅速に書き込むアプリケーションに最適です。

JavaでのOracle XML DB HTTPサーブレットの作成

Oracle XML DBは、FTP、HTTP 1.1、WebDAVおよびJavaサーブレットをサポートするプロトコル・サーバーを提供します。Oracle XML DBは、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サーブレットは、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要素名 定義元 サポートの有無 説明 コメント

auth-method

Java

非サポート

アクセスに必要なHTTP認証方式を指定します。

--

charset

Oracle

サポート

IANAキャラクタ・セット名を指定します。

ISO8859、UTF-8などです。

charset-mapping

Oracle

サポート

ファイル名の拡張子とキャラクタ・セットの間のマッピングを指定します。

--

context-param

Java

非サポート

Webアプリケーション用のパラメータを指定します。

現在はサポートされていません。

description

Java

サポート

サーブレットまたはWebアプリケーションを説明する文字列です。

サーブレット用にサポートされています。

display-name

Java

サポート

サーブレットまたはWebアプリケーションで表示する文字列です。

サーブレット用にサポートされています。

distributable

Java

非サポート

すべてのインスタンスが同じJava仮想マシンで実行していない場合に、このサーブレットが機能できるかどうかを示します。

Oracle Databaseで実行するすべてのサーブレットは、distributableである必要があります。

errnum

Oracle

サポート

Oracleエラー番号です。

『Oracle Databaseエラー・メッセージ』を参照してください。

error-code

Java

サポート

HTTP(S)エラー・コードです。

RFC 2616で定義されています。

error-page

Java

サポート

エラーが発生した場合のリダイレクト先のURLを定義します。

HTTP(S)エラー、不明なJava例外または不明なOracleエラー・メッセージで指定できます。

exception-type

Java

サポート

エラー・ページにマップされたJava例外のクラス名です。

--

extension

Java

サポート

MIMEタイプやキャラクタ・セットなどに関連付けるために使用するファイル名の拡張子です。

--

facility

Oracle

サポート

エラー・ページをマッピングするためのOracle機能コードです。

ORA、PLSなどです。

form-error-page

Java

非サポート

フォーム・ログインの試行に対するエラー・ページです。

現在はサポートされていません。

form-login-config

Java

非サポート

フォームベースのログインの構成仕様です。

現在はサポートされていません。

form-login-page

Java

非サポート

フォームベースのログイン・ページのURLです。

現在はサポートされていません。

icon

Java

サポート

サーブレットに関連付けられたアイコンのURLです。

サーブレット用にサポートされています。

init-param

Java

サポート

サーブレットの初期化パラメータです。

--

jsp-file

Java

非サポート

サーブレットに使用するJavaServer Pagesファイルです。

サポートされていません。

lang

Oracle

サポート

IANA言語名です。

en-USなどです。

lang-mapping

Oracle

サポート

ファイル名の拡張子と言語コンテンツの間のマッピングを指定します。

--

large-icon

Java

サポート

アイコン表示用の大きいサイズのアイコンです。

--

load-on-startup

Java

サポート

サーブレットの起動時にロードするかどうかを指定します。

--

location

Java

サポート

エラー・ページのURLを指定します。

ローカル・パス名またはHTTP(S) URLを指定できます。

login-config

Java

非サポート

認証方式を指定します。

現在はサポートされていません。

mime-mapping

Java

サポート

コンテンツのファイル名の拡張子とMIMEタイプの間のマッピングを指定します。

--

mime-type

Java

サポート

リソース・コンテンツのMIMEタイプ名です。

text/xml、application/octet-streamなどです。

OracleError

Oracle

サポート

エラー・ページに関連付けるOracleエラーを指定します。

--

param-name

Java

サポート

サーブレットまたはServletContextのパラメータ名です。

サーブレット用にサポートされています。

param-value

Java

サポート

パラメータの値です。

--

realm-name

Java

非サポート

認証に使用するHTTP(S)レルムです。

現在はサポートされていません。

role-link

Java

サポート

特定のユーザーがサーブレットにアクセスするために必要なロールを指定します。

データベース・ロール名を参照します。デフォルトでは、大文字にする必要があります。

role-name

Java

サポート

ロールのサーブレット名です。

データベース・ロールを呼び出すための別の名前です。サーブレットのAPIで使用します。

security-role

Java

非サポート

サーブレットが使用するロールを定義します。

サポートされていません。ロールは、SQLのCREATE ROLEを使用して手動で作成する必要があります。

security-role-ref

Java

サポート

サーブレットとロール間の参照です。

--

servlet

Java

サポート

サーブレットの構成情報です。

--

servlet-class

Java

サポート

Javaサーブレットのクラス名を指定します。

--

servlet-language

Oracle

サポート

サーブレットを作成するプログラミング言語を指定します。

Java、C、PL/SQLのいずれかです。現在、顧客定義のサーブレットには、Javaのみがサポートされています。

servlet-mapping

Java

サポート

サーブレットを関連付けるファイル名のパターンを指定します。

Javaで定義されたすべてのマッピングがサポートされています。

servlet-name

Java

サポート

サーブレットの文字列名です。

サーブレットのAPIで使用します。

servlet-schema

Oracle

サポート

JavaクラスがロードされるOracleスキーマです。指定しない場合、デフォルトのリゾルバ仕様を使用してスキーマが検索されます。

これが指定されない場合、サーブレットをSYSスキーマにロードして、すべてのユーザーがアクセスできるようにするか、またはデフォルトのJavaクラス・リゾルバを変更する必要があります。servlet-schemaの値は、二重引用符で囲まないかぎり大文字になることに注意してください。

session-config

Java

非サポート

HTTPSessionの構成情報です。

HTTPSessionはサポートされません。

session-timeout

Java

非サポート

HTTP(S)セッションのタイムアウトです。

HTTPSessionはサポートされません。

small-icon

Java

サポート

サーブレットに関連付けられた小さいアイコンです。

--

taglib

Java

非サポート

JSPタグ・ライブラリです。

JSPは現在サポートされていません。

taglib-uri

Java

非サポート

web.xmlファイルに相対的なJSPタグ・ライブラリの記述ファイルのURIです。

JSPは現在サポートされていません。

taglib-location

Java

非サポート

タグ・ライブラリが格納されているWebアプリケーションのルートに相対的なパス名です。

JSPは現在サポートされていません。

url-pattern

Java

サポート

サーブレットに関連付けられたURLパターンです。

Javaサーブレット2.2仕様の第10項を参照してください。

web-app

Java

非サポート

Webアプリケーションの構成です。

現在、1つのWebアプリケーションのみがサポートされています。

welcome-file

Java

サポート

ウェルカム・ファイルの名前を指定します。

--

welcome-file-list

Java

サポート

HTTP GETリクエストを使用してフォルダが参照された場合に表示するファイルのリストを定義します。

index.htmlなどです。



注意:

  • Javaによって web.xmlファイルに定義されたパラメータ(env-entryenv-entry-nameenv-entry-valueenv-entry-typeejb-refejb-ref-typehomeremoteejb-linkresource-refres-ref-name、res-type、res-auth)は、J2EE準拠のEnterprise Java Beanコンテナでのみ使用でき、完全なJ2EE環境をサポートしないJavaサーブレット・コンテナには必要ありません。

  • security-constraintweb-resource-collectionweb-resource-namehttp-methoduser-data-constrainttransport-guaranteeおよびauth-constrainの各要素は、リソースにアクセス制御を定義するために使用されます。Oracle XML DBは、アクセス制御リスト(ACL)を使用してこの機能を提供します。ACLは、指定されたリソースへのアクセス権を持つプリンシパルを決定するアクセス制御エントリ(ACE)のリストです。web.xmlファイルを使用したACLの生成は、今後のリリースでサポートされます。



関連項目:

/xdbconfig.xmlファイルの構成の詳細は、第34章「Oracle XML DBの管理」を参照してください。

Oracle XML DBサーブレットに対するHTTPリクエストの処理

Oracle XML DBは、次の手順を実行してHTTPリクエストを処理します。

  1. 接続が確立されていない場合、Oracleリスナーは接続を共有サーバー・ディスパッチャに渡します。

  2. 新しいHTTPリクエストを受信すると、ディスパッチャは共有サーバーを起動します。

  3. HTTPヘッダーは、適切な構造に解析されます。

  4. 共有サーバーは、Oracle XML DBセッション・プールが使用可能な場合、そこからデータベース・セッションの割当てを試行します。Oracle XML DBセッション・プールが使用できない場合、新しいセッションを作成します。

  5. 新しいデータベース・コールおよび新しいデータベース・トランザクションが開始されます。

  6. HTTP(S)に認証ヘッダーが含まれている場合、セッションはそのデータベース・ユーザーとしてSQL*Plusにログインしている場合と同様に認証されます。認証情報が含まれず、リクエストがGETまたはHEADである場合、Oracle XML DBはセッションをANONYMOUSユーザーとして認証しようとします。このデータベース・ユーザーのアカウントがロックされている場合、認証されないアクセスは許可されません。

  7. Javaサーブレット2.2の仕様で指定されているとおり、HTTPリクエストのURLがxdbconfig.xmlファイルのサーブレットと一致しているかどうかが確認されます。

  8. Oracle XML DBサーブレット・コンテナは、Oracle内部のJava VMで起動されます。指定したサーブレットが初期化されていない場合は、初期化されます。

  9. サーブレットは、ServletInputStreamから入力を読み取り、ServletOutputStreamに出力を書き込み、service()メソッドから戻ります。

  10. 不明なOracleエラーが発生した場合、セッションはセッション・プールに戻されます。

セッション・プールおよびOracle XML DBサーブレット

Oracle Databaseは、データベース・セッションごとに1つのJVMを使用します。セッション・プールから再利用されるセッションは、セッションが最後に使用されてからは、JVM(Java静的変数)内でどのような状態も保持します。

これは、メタデータなど、ユーザー固有でないJava状態をキャッシュする場合に有効ですが、保護ユーザーのデータはJava静的メモリーに格納しないでください。保護ユーザーのデータをJava静的メモリーに格納した場合、アプリケーションによってセキュリティ・ホールが出現する可能性があります。

ネイティブなXMLストリームのサポート

DOMノード・クラスは、write()というOracle固有のメソッドを持ちます。このメソッドは次の引数を取り、voidを戻します。

  • java.io.OutputStreamストリーム: XMLテキストの書き込み先Javaストリーム。

  • String charEncoding: XMLテキストを書き込むキャラクタ・エンコーディング。NULLの場合、データベース・キャラクタ・セットが使用されます。

  • Short indent: ネストしたXML要素のインデントの文字数。

提供されたストリームがデータベース内部で提供されるServletOutputStreamである場合、Javaメソッドwrite()には、ショートカットが実装されます。ノードのコンテンツは、出力ソケットにネイティブなコードのXMLで直接書き込まれます。これによって、JavaオブジェクトまたはUnicode(Java文字列に必要)との間の変換が回避され、パフォーマンスが向上します。

Oracle XML DBサーブレットのAPI

Oracle XML DBサーブレットでサポートされるAPIは、Javaサーブレット2.2仕様で定義されます。現在、Javaサーブレット2.2仕様のJavadocは、http://java.sun.com/products/servlet/2.2/javadoc/index.htmlのサイトで参照できます。

表32-2に、未実装のJavaサーブレット2.2メソッドをリストします。実行時に例外が発生します。

表32-2 未実装のJavaサーブレット2.2メソッド

インタフェース 未実装のメソッド
HttpServletRequest

getSession()、isRequestedSessionIdValid()

HttpSession

all

HttpSessionBindingListener

all


Oracle XML DBサーブレットの例

例32-1に、ファイル・リソース/public/test/foo1.textの内容を出力する単純なサーブレットを示します。

例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(); }}}

サーブレットをインストールするには、サーブレットをコンパイルしてからOracle Databaseにロードします。

% loadjava –grant public –u quine/curry –r test.class

最後に、例32-2に示すようにサーブレットを登録してマップし、URLと関連付けます。

例32-2 Oracle XML DBサーブレットの登録およびマッピング

EXEC DBMS_XDB.addServlet('TestServletFoo', 'Java', 'TestServletFoo',
                         NULL, NULL, 'test', NULL, NULL, 'XDB');

EXEC DBMS_XDB.addServletMapping('/public/test/foo1.txt', 'TestServletFoo');

COMMIT;