ヘッダーをスキップ

Oracle Application Server Containers for J2EE JavaServer Pages 開発者ガイド
10gリリース2(10.1.2)
B15632-02
目次
目次
索引
索引

戻る 次へ

4
プログラミングに関する基本的な考慮事項

この章では、JSPページのプログラミングに関する基本的な考慮事項について、例を示して説明します。JSPとサーブレット間の相互作用およびデータベース・アクセスについても説明します。

次の項目について説明します。

JSPとサーブレット間の相互作用

JSPページのコーディングは多くの点で便利ですが、サーブレットのコールが必要な場合があります。その一例は、「JSPページでバイナリ・データを回避する理由」で説明するように、バイナリ・データを出力する場合です。

このため、サーブレットとJSPページ間での往復が、1つのアプリケーション内で必要になる場合があります。次の各項で、その方法を説明します。

JSPページからのサーブレットの起動

あるJSPページから別のJSPページを起動する場合と同様に、jsp:include操作タグとjsp:forward操作タグを使用して、JSPページからサーブレットを起動できます(「標準アクション: JSPタグ」を参照)。次に例を示します。

<jsp:include page="/servlet/MyServlet" flush="true" />

ページの実行中にこの文が出現すると、ページ・バッファがブラウザに出力され、サーブレットが実行されます。サーブレットの実行が終了すると、制御がJSPページに戻されて、ページの実行が続行されます。この機能は、JSPページ間におけるjsp:include操作タグと同じ機能です。

また、JSPページ間におけるjsp:forward操作タグと同様に、次の文は、ページ・バッファをクリアし、JSPページの実行を終了して、サーブレットを実行します。

<jsp:forward page="/servlet/MyServlet" />

JSPページから起動したサーブレットへのデータの受渡し

JSPページからサーブレットに動的にインクルードまたは転送を行う場合は、jsp:paramタグを使用して、サーブレットにデータを渡すことができます(別のJSPページへのインクルードまたは転送でも同様です)。

jsp:paramタグは、jsp:includeタグまたはjsp:forwardタグ内で使用できます。次に例を示します。

<jsp:include page="/servlet/MyServlet" flush="true" >
   <jsp:param name="username" value="Smith" />
   <jsp:param name="userempno" value="9876" />
</jsp:include>

jsp:paramタグの詳細は、「標準アクション: JSPタグ」を参照してください。

適切なスコープのJavaBean、またはHTTPリクエスト・オブジェクトの属性を使用して、JSPページとサーブレットとの間でデータの受渡しを行うこともできます。リクエスト・オブジェクトの属性の使用方法は、「JSPページとサーブレット間でのデータの受渡し」で説明します。

サーブレットからのJSPページの起動

標準のjavax.servlet.RequestDispatcherインタフェースの機能を使用すると、サーブレットからJSPページを起動できます。この機能を使用するには、次の手順に従ってコードを作成します。

  1. サーブレット・インスタンスからサーブレット・コンテキスト・インスタンスを取得します。

    ServletContext sc = this.getServletContext();
    
    
  2. サーブレット・コンテキスト・インスタンスからリクエスト・ディスパッチャを取得し、ターゲットのJSPページのページ相対パスまたはアプリケーション相対パスをgetRequestDispatcher()メソッドへの入力として指定します。

    RequestDispatcher rd = sc.getRequestDispatcher("/jsp/mypage.jsp");
    
    

    この手順の実行前か実行中に、HTTPリクエスト・オブジェクトの属性を必要に応じて使用して、JSPページにデータを受け渡すことができます。詳細は、次項の「JSPページとサーブレット間でのデータの受渡し」を参照してください。

  3. リクエスト・ディスパッチャのinclude()メソッドまたはforward()メソッドを起動し、HTTPリクエスト・オブジェクトとレスポンス・オブジェクトを引数として指定します。例:

    rd.include(request, response);
    
    

    または

    rd.forward(request, response);
    
    

    これらのメソッドの機能は、jsp:includeタグおよびjsp:forwardタグの機能と同じです。include()メソッドは一時的に制御を移すのみで、後で、起動したサーブレットに実行の制御が戻されます。

    forward()メソッドは、出力バッファをクリアすることに注意してください。


    注意: リクエスト・オブジェクトとレスポンス・オブジェクトは、標準のサーブレット機能(javax.servlet.http.HttpServletクラスに指定されているdoGet()メソッドなど)を使用して、事前に取得されています。 

JSPページとサーブレット間でのデータの受渡し

前の項の「サーブレットからのJSPページの起動」で説明したように、リクエスト・ディスパッチャを使用してサーブレットからJSPページを起動するとき、HTTPリクエスト・オブジェクトを必要に応じて使用して、データを受け渡すことができます。この操作は、次のいずれかの方法で実行できます。

JSPとサーブレット間の相互作用のサンプル

この項では、前の各項で説明した機能を使用したJSPページとサーブレットのサンプルを示します。JSPページのJsp2Servlet.jspには、サーブレットのMyServletがインクルードされ、このサーブレットには別のJSPページのwelcome.jspがインクルードされます。

Jsp2Servlet.jspのコード

<HTML>
<HEAD> <TITLE> JSP Calling Servlet Demo </TITLE> </HEAD>
<BODY>

<!-- Forward processing to a servlet -->
<% request.setAttribute("empid", "1234"); %>
<jsp:include page="/servlet/MyServlet?user=Smith" flush="true"/>

</BODY>
</HTML>

MyServlet.javaのコード

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.PrintWriter;
import java.io.IOException;

public class MyServlet extends HttpServlet {

    public void doGet (HttpServletRequest request,
                       HttpServletResponse response)
      throws IOException, ServletException {
      PrintWriter out= response.getWriter();
      out.println("<B><BR>User:" + request.getParameter("user"));
      out.println
          (", Employee number:" + request.getAttribute("empid") + "</B>");
      this.getServletContext().getRequestDispatcher
                       ("/jsp/welcome.jsp").include(request, response);
    }
}

welcome.jspのコード

<HTML>
<HEAD> <TITLE> The Welcome JSP  </TITLE> </HEAD>
<BODY>

<H3> Welcome! </H3>
<P><B> Today is <%= new java.util.Date() %>.  Have a nice day! </B></P>
</BODY>
</HTML>

JSPデータ・アクセスに関するサポートと機能

次の各項では、データへのアクセス時に考慮する必要があるOC4J JSPとOracleの機能について説明します。

データ・アクセスに対するJSPサポートの概要

JDBC APIは単なる一連のJavaインタフェースであるため、JavaServer Pagesのテクノロジは、JSPスクリプトレット内でのこのAPIの使用を直接サポートします。

Oracle JDBCには、いくつかのドライバが用意されています。1)JDBC OCIドライバは、Oracleクライアントのインストールで使用します。2)100% JavaのJDBC Thinドライバは、基本的にすべてのクライアント側(アプレットも含む)で使用できます。3)JDBCサーバー側Thinドライバは、Oracle Databaseインスタンスに別のOracle Databaseインスタンス内からアクセスするために使用します。4)JDBCサーバー側内部ドライバは、Javaコードが(Javaストアド・プロシージャなどから)実行されているデータベースにアクセスするために使用します。このマニュアルでは、JDBCに関する基本的な知識があることを前提としています。『Oracle Database JDBC開発者ガイドおよびリファレンス』を参照してください。

OC4JのJSPコンテナは、EJBコールもサポートします。

さらに、JavaServer Pages標準タグ・ライブラリ(JSTL)のSQLタグ、およびOC4Jで提供されるJavaBeansおよびカスタムSQLタグがあります。詳細は、『Oracle Application Server Containers for J2EE JSPタグ・ライブラリおよびユーティリティ・リファレンス』を参照してください。

JDBCを使用したJSPデータ・アクセスのサンプル

次の例では、ユーザーがHTMLフォームを使用して入力(ボックスに入力し「Ask Oracle」ボタンをクリック)した検索条件から、動的に問合せを作成します。指定の問合せを実行するには、JSP宣言で定義したrunQuery()というメソッドで、JDBCコードを使用します。また、出力を作成するには、JSP宣言でformatResult()メソッドを定義します。runQuery()メソッドでは、scottスキーマとパスワードtigerを使用します

HTMLのINPUTタグによって、フォームに入力された文字列はcondと命名されます。したがって、condは、このHTTPリクエストの暗黙的なrequestオブジェクトのgetParameter()メソッドに対する入力パラメータであり、runQuery()メソッドに対する入力パラメータでもあります(このメソッドによって、cond文字列が問合せのWHERE句に配置されます)。


注意:
  • この例では、<%!...%>宣言構文を使用してrunQuery()メソッドが定義されていますが、かわりに、<%...%>スクリプトレット構文を使用することもできます。

  • この例では、JDBC OCIドライバを使用するため、Oracleクライアントのインストールが必要です。このサンプルを実行する場合は、適切なJDBCドライバと接続文字列を使用してください。

 

<%@ page language="java" import="java.sql.*" %>
<HTML>
<HEAD> <TITLE> The JDBCQuery JSP  </TITLE> </HEAD>
<BODY BGCOLOR="white">
<% String searchCondition = request.getParameter("cond");
   if (searchCondition != null) { %>
      <H3> Search results for  <I> <%= searchCondition %> </I> </H3>
      <B> <%= runQuery(searchCondition) %> </B> <HR><BR>
<% }  %>
<B>Enter a search condition:</B>
<FORM METHOD="get">
<INPUT TYPE="text" NAME="cond" SIZE=30>
<INPUT TYPE="submit" VALUE="Ask Oracle");
</FORM>
</BODY>
</HTML>
<%-- Declare and define the runQuery() method. --%>
<%! private String runQuery(String cond) throws SQLException {
     Connection conn = null;
     Statement stmt = null;
     ResultSet rset = null;
     try {
        DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
        conn = DriverManager.getConnection("jdbc:oracle:oci:@",
                                           "scott", "tiger");
        stmt = conn.createStatement();
        // dynamic query
        rset = stmt.executeQuery ("SELECT ename, sal FROM scott.emp "+
                           (cond.equals("") ? "" : "WHERE " + cond ));
       return (formatResult(rset));
     } catch (SQLException e) {
         return ("<P> SQL error: <PRE> " + e + " </PRE> </P>¥n");
     } finally {
         if (rset!= null) rset.close();
         if (stmt!= null) stmt.close();
         if (conn!= null) conn.close();
     }
  }
  private String formatResult(ResultSet rset) throws SQLException {
    StringBuffer sb = new StringBuffer();
    if (!rset.next())
      sb.append("<P> No matching rows.<P>¥n");
    else {  sb.append("<UL>");
            do {  sb.append("<LI>" + rset.getString(1) +
                            " earns $ " + rset.getInt(2) + ".</LI>¥n");
            } while (rset.next());
           sb.append("</UL>");
    }
    return sb.toString();
  }
%>

図4-1は、次の入力に対するサンプル出力を示しています。

sal >= 2500 AND sal < 5000

図4-1    問合せ結果のサンプル


画像の説明

JDBCパフォーマンス強化機能の使用

OC4JのJSPアプリケーションでは、次のパフォーマンス強化機能を使用できます。これらの機能は、Oracle JDBC拡張機能によってサポートされます。

これらのパフォーマンス機能のほとんどは、(DBBeanではなく)データ・アクセス用JavaBeansのOracle ConnBeanConnCacheBeanによってサポートされます。これらのBeanについては、『Oracle Application Server Containers for J2EE JSPタグ・ライブラリおよびユーティリティ・リファレンス』を参照してください。

データベース接続のキャッシング

新規のデータベース接続の作成はコストがかかる操作であるため、できるだけ回避する必要があります。かわりに、データベース接続のキャッシュを使用します。JSPアプリケーションは、物理的な接続の既存のプールから論理的な接続を取得し、終了時にその接続をプールに戻すことができます。

接続プールは、4つのJSPスコープ(applicationsessionpageまたはrequest)のいずれかに作成できます。可能な最大のスコープを使用すると最も効率的で、Webサーバーで許可されている場合はapplicationスコープ、それ以外の場合はsessionスコープを使用します。

JDBC 2.0の標準拡張機能で指定されている標準接続プーリングに基づいたOracle JDBC接続キャッシング・スキームは、OC4Jが提供するデータ・アクセス用JavaBeanのConnCacheBeanに実装されています。データ・アクセス用JavaBeanのConnBeanがサポートする標準のデータソース接続プーリング機能も使用できます。これらのBeanについては、『Oracle Application Server Containers for J2EE JSPタグ・ライブラリおよびユーティリティ・リファレンス』を参照してください。

Oracle JDBC接続のキャッシング・スキームの詳細は、『Oracle Database JDBC開発者ガイドおよびリファレンス』を参照してください。

JDBC文のキャッシング

Oracle JDBCの拡張機能である文のキャッシング機能は、単一の物理的な接続内(ループ内、または繰り返しコールされるメソッド内)で繰り返し使用される実行文をキャッシングして、パフォーマンスを向上させます。文をキャッシュすると、その文を実行するたびに文を再解析したり、文オブジェクトを再作成したり、パラメータ・サイズ定義を再計算する必要はありません。

Oracle JDBCの文のキャッシング・スキームは、OC4Jが提供するデータ・アクセス用JavaBeansのConnBeanConnCacheBeanに実装されています。これらのBeanには、それぞれstmtCacheSizeプロパティがあり、jsp:setPropertyタグまたはBeanのsetStmtCacheSize()メソッドを使用して設定できます。Beanの詳細は、『Oracle Application Server Containers for J2EE JSPタグ・ライブラリおよびユーティリティ・リファレンス』を参照してください。

Oracle JDBC文のキャッシング・スキームの詳細は、『Oracle Database JDBC開発者ガイドおよびリファレンス』を参照してください。


重要: 文は、単一の物理的な接続内でのみキャッシュできます。接続キャッシュに対して文のキャッシング機能を有効にすると、プールされた単一の接続オブジェクトから複数の論理接続オブジェクト間で文をキャッシュできます。ただし、プールされた複数の接続オブジェクト間ではキャッシュできません。 

バッチ更新

Oracle JDBCのバッチ更新機能は、バッチの値(制限)を、プリコンパイルされたSQL文の各オブジェクトに関連付けます。executeメソッドがコールされるたびにプリコンパイルされたSQL文を実行するJDBCドライバのかわりにバッチ更新を使用すると、ドライバは、その文を累積した実行リクエストのバッチに追加します。バッチの値に達すると、ドライバは、実行のためにすべての操作をデータベースに渡します。たとえば、バッチの値が10の場合は、10個の操作の各バッチがデータベースに送信され、1回の送信ですべての操作が処理されます。

OC4Jは、データ・アクセス用JavaBeanのConnBeanexecuteBatchプロパティを使用して、Oracle JDBCのバッチ更新を直接サポートします。このプロパティは、jsp:setPropertyタグまたはBeanのsetterメソッドを使用して設定できます。かわりにConnCacheBeanを使用している場合は、接続内または作成する文オブジェクト内でOracle JDBC機能を使用して、バッチ更新を有効にできます。これらのBeanについては、『Oracle Application Server Containers for J2EE JSPタグ・ライブラリおよびユーティリティ・リファレンス』を参照してください。

Oracle JDBCのバッチ更新の詳細は、『Oracle Database JDBC開発者ガイドおよびリファレンス』を参照してください。

行のプリフェッチ

問合せ結果セットを移入する場合、Oracle JDBCの行のプリフェッチ機能によって、データベースへのトリップごとにクライアントにプリフェッチする行数を決定できます。これによって、サーバーへのラウンドトリップ回数が減少します。

OC4Jは、データ・アクセス用JavaBeanのConnBeanpreFetchプロパティを使用して、Oracle JDBCの行のプリフェッチを直接サポートします。このプロパティは、jsp:setPropertyタグまたはBeanのsetterメソッドを使用して設定できます。かわりにConnCacheBeanを使用している場合は、接続内または作成する文オブジェクト内でOracle JDBC機能を使用して、行のプリフェッチを有効にできます。これらのBeanについては、『Oracle Application Server Containers for J2EE JSPタグ・ライブラリおよびユーティリティ・リファレンス』を参照してください。

Oracle JDBCの行のプリフェッチの詳細は、『Oracle Database JDBC開発者ガイドおよびリファレンス』を参照してください。

行セットのキャッシング

キャッシュ内の行セットは、切断された、シリアライズ可能でスクロール可能なコンテナを、取得したデータに提供します。この機能は、頻繁に変更しない小規模なデータ・セットに対して有効です。特に、クライアントが頻繁かつ継続的に情報へのアクセスを要求する場合に便利です。これに対して、標準の結果セットを使用する場合は、基礎になる接続とリソースを保持する必要があります。ただし、キャッシュ内の行セットが大規模な場合は、アプリケーション・サーバーのメモリーを大量に消費することに注意してください。

Oracle DatabaseのOracle JDBC実装では、キャッシュ内の行セットを提供します。Oracle JDBCドライバを使用している場合は、次の例に示すように、JSPページ内でコードを使用して、キャッシュ内の行セットを作成および移入します。

CachedRowSet crs = new CachedRowSet();
crs.populate(rset); // rset is a previously created JDBC ResultSet object.

行セットが移入されると、元の結果セットの取得時に使用した、接続と文オブジェクトがクローズされます。

Oracle JDBCのキャッシュ内の行セットの詳細は、『Oracle Database JDBC開発者ガイドおよびリファレンス』を参照してください。

JSPページからのEJBコール

JSPページは、EJBをコールして追加処理またはデータ・アクセスを実行できます。典型的なアプリケーション設計では、クライアント・リクエストの初期処理を行うためにJavaServer Pagesをフロントエンドとして使用し、Enterprise JavaBeansをコールして、データ・ソースに対する読取りや書込みなどの作業を実行します。次の各項では、EJBの使用方法の概要について説明します。

EJBの構成とデプロイの概要

JSPページからEJBをコールするための構成およびデプロイ手順は、サーブレットからEJBをコールする手順と似ています。この手順に関しては、『Oracle Application Server Containers for J2EEサーブレット開発者ガイド』を参照してください。手順は次のとおりです。

EJBコールのコード手順とアプローチ

JSPページでEJBを起動する主な手順は、次のとおりです。

  1. Beanホームとリモート・インタフェース用のEJBパッケージを、EJBコールを行う各JSPページにインポートします。pageディレクティブを使用します。

  2. JNDIを使用して、EJBホーム・インタフェースをルックアップします。

  3. ホームからEJBリモート・オブジェクトを作成します。

  4. リモート・オブジェクトでビジネス・メソッドを起動します。

JSPページでは、ほとんどのサーブレット・コードをスクリプトレットのフォームで使用できるため、サーブレットで使用するコードと同じコードをスクリプトレットで使用すると、EJBをJSPページから簡単にコールできます。この方法は、手順2〜4を実行する1つの方法です。

または、OC4Jが提供するEJBタグ・ライブラリのタグを使用することもできます。詳細は、次項の「OC4JのEJBタグ・ライブラリの使用」を参照してください。タグによって、コーディングが簡素化されます。基本的に、タグを使用すると、JSPページで共通に使用する通常のJavaBeansと同様に、Enterprise JavaBeansを処理できます。

OC4JのEJBタグ・ライブラリの使用

前項の「EJBコールのコード手順とアプローチ」を参照してください。前項で説明したように、pageディレクティブで適切なパッケージをインポートします。次の手順に従って、OC4JのEJBタグを使用します。

EJBタグ・ライブラリと詳細なタグの構文については、『Oracle Application Server Containers for J2EE JSPタグ・ライブラリおよびユーティリティ・リファレンス』を参照してください。

タグ・ライブラリを使用する場合とスクリプトレット・コードを使用する場合のデプロイ要件は同じです。他のタグ・ライブラリと同様に、TLDとライブラリ・サポート・クラス(タグ・ハンドラ・クラスとタグ補足情報クラス)は、アプリケーションに対してアクセス可能であることが必要です。

OracleXMLQueryクラス

oracle.xml.sql.query.OracleXMLQueryクラスは、データベース問合せで使用するXML機能に対するOracle Database XML SQL Utilityの一部です。このクラスにはxsu12.jarファイルが必要です。このファイルは、OC4Jが提供する一部のカスタム・タグとJavaBeansのXML機能にも必要です。このファイルは、Oracle DatabaseおよびOracle Application Serverで提供されます。

OracleXMLQueryクラス、およびXML SQL Utilityの他の機能については、『Oracle XML Developer's Kitプログラマーズ・ガイド』を参照してください。

JSPリソース管理

次の各項では、リソース管理に関する標準機能とOracleの付加価値機能について説明します。

標準セッションのリソース管理: HttpSessionBindingListener

JSPページでは、実行中に取得したリソース(JDBC接続、文、結果セット・オブジェクトなど)の適切な管理が必要です。標準のjavax.servlet.httpパッケージには、sessionスコープのリソースを管理するために、HttpSessionBindingListenerインタフェースとHttpSessionBindingEventクラスが用意されています。たとえば、sessionスコープの問合せBeanはこの機能を使用して、Beanがインスタンス化されるときにデータベース・カーソルを取得し、HTTPセッションが終了するときにそのカーソルをクローズできます(「JDBCを使用したJSPデータ・アクセスのサンプル」の例では、問合せごとに接続をオープンしてクローズするため、オーバーヘッドが増大します)。

この項では、HttpSessionBindingListenervalueBound()メソッドとvalueUnbound()メソッドの使用方法について説明します。


注意: Beanインスタンスは、HTTPセッション・オブジェクトのイベント通知リストに登録する必要がありますが、jsp:useBean文によって自動的に登録されます。 

valueBound()メソッドとvalueUnbound()メソッド

HttpSessionBindingListenerインタフェースを実装するオブジェクトは、valueBound()メソッドとvalueUnbound()メソッドを実装できます。いずれのメソッドも、HttpSessionBindingEventインスタンスを入力として取得します。これらのメソッドは、サーブレット・コンテナによってコールされます。valueBound()メソッドは、オブジェクトがセッションに格納されるときにコールされ、valueUnbound()メソッドは、オブジェクトがセッションから削除されるか、あるいはセッションがタイムアウトまたは無効になるとコールされます。開発者は通常、オブジェクトが保持するリソースを解放するためにvalueUnbound()メソッドを使用します(後述の例では、データベース接続の解放で使用します)。

次の「JDBCQueryBean JavaBeanコード」の項では、HttpSessionBindingListenerを実装するJavaBeanのサンプルとそのBeanをコールするJSPページのサンプルを示します。

JDBCQueryBean JavaBeanコード

次に、JDBCQueryBeanのサンプル・コードを示します。これは、HttpSessionBindingListenerインタフェースを実装するJavaBeanです。ここでは、データベース接続用にJDBC OCIドライバを使用しています。このサンプル・コードを実行する場合は、適切なJDBCドライバと接続文字列を使用してください。

JDBCQueryBeanは、HTMLリクエストから検索条件を取得し(「UseJDBCQueryBean JSPページ」を参照)、その検索条件に基づいて動的な問合せを実行し、結果を出力します。

このクラスは、セッション終了時にデータベース接続をクローズするvalueUnbound()メソッド(HttpSessionBindingListenerインタフェースで指定されます)も実装します。

package mybeans;

import java.sql.*;
import javax.servlet.http.*;

public class JDBCQueryBean implements HttpSessionBindingListener
{
  String searchCond = "";
  String result = null;

  public void JDBCQueryBean() {
  }

  public synchronized String getResult() {
    if (result != null) return result;
    else return runQuery();
  }

  public synchronized void setSearchCond(String cond) {
    result = null;
    this.searchCond = cond;
  }

  private Connection conn = null;

  private String runQuery() {
    StringBuffer sb = new StringBuffer();
    Statement stmt = null;
    ResultSet rset = null;
    try {
      if (conn == null) {
        DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
        conn = DriverManager.getConnection("jdbc:oracle:oci8:@",
                                           "scott", "tiger");

      }

      stmt = conn.createStatement();
      rset = stmt.executeQuery ("SELECT ename, sal FROM scott.emp "+
            (searchCond.equals("") ? "" : "WHERE " + searchCond ));
      result = formatResult(rset);
      return result;

    } catch (SQLException e) {
      return ("<P> SQL error: <PRE> " + e + " </PRE> </P>¥n");
    }
    finally {
      try {
        if (rset != null) rset.close();
        if (stmt != null) stmt.close();
      }
      catch (SQLException ignored) {}
    }
  }

  private String formatResult(ResultSet rset) throws SQLException  {
    StringBuffer sb = new StringBuffer();
    if (!rset.next())
      sb.append("<P> No matching rows.<P>¥n");
    else {
      sb.append("<UL><B>");
      do {  sb.append("<LI>" + rset.getString(1) +
            " earns $ " + rset.getInt(2) + "</LI>¥n");
      } while (rset.next());
      sb.append("</B></UL>");
    }
    return sb.toString();
  }

  public void valueBound(HttpSessionBindingEvent event) {
    // do nothing -- the session-scope bean is already bound
  }

  public synchronized void valueUnbound(HttpSessionBindingEvent event) {
    try {
      if (conn != null) conn.close();
    }
    catch (SQLException ignored) {}
  }
}


注意: 前述のコードは、サンプル用です。大規模なWebアプリケーションでデータベース接続のプーリングを処理する方法としては、必ずしもお薦めできません。 

UseJDBCQueryBean JSPページ

次のJSPページでは、前の「JDBCQueryBean JavaBeanコード」の項で定義したJDBCQueryBean JavaBeanを使用し、sessionスコープを使用してBeanを起動します。ここでは、JDBCQueryBeanを使用して、ユーザーが入力した検索条件と一致する従業員名を表示します。

JDBCQueryBeanは、このJSPページのjsp:setPropertyタグから検索条件を取得します。このタグは、ユーザーがHTMLフォームを使用して入力したsearchCondリクエスト・パラメータの値に従って、BeanのsearchCondプロパティを設定します。HTMLのINPUTタグによって、フォームに入力された検索条件はsearchCondと命名されます。

<jsp:useBean id="queryBean" class="mybeans.JDBCQueryBean" scope="session" />
<jsp:setProperty name="queryBean" property="searchCond" />

<HTML>
<HEAD> <TITLE> The UseJDBCQueryBean JSP  </TITLE> </HEAD>
<BODY BGCOLOR="white">

<% String searchCondition = request.getParameter("searchCond");
   if (searchCondition != null) { %>
      <H3> Search results for : <I> <%= searchCondition %> </I> </H3>
      <%= queryBean.getResult() %>
      <HR><BR>
<% }  %>

<B>Enter a search condition for the EMP table:</B>

<FORM METHOD="get">
<INPUT TYPE="text" NAME="searchCond" VALUE="ename LIKE 'A%' " SIZE="40">
<INPUT TYPE="submit" VALUE="Ask Oracle">
</FORM>

</BODY>
</HTML>

図4-2に、このページの入力と出力のサンプルを示します。

図4-2    JDBCQueryBeanを使用した問合せ結果のサンプル


画像の説明

HttpSessionBindingListenerのメリット

前述の例では、HttpSessionBindingListener機能のかわりに、JavaBeanのfinalize()メソッドで接続をクローズできます。finalize()メソッドは、セッションのクローズ後にBeanのガベージ・コレクションが実行されるとコールされます。ただし、HttpSessionBindingListenerインタフェースの動作は、finalize()メソッドよりも確実に予測できます。ガベージ・コレクションの頻度は、アプリケーションのメモリー消費パターンによって異なります。これに対して、HttpSessionBindingListenerインタフェースのvalueUnbound()メソッドは、セッションの停止時に確実にコールされます。

リソース管理のためのOracleの付加価値機能の概要

OC4Jなどのサーブレット2.3環境では、OC4J JSPはJspScopeListenerインタフェースを提供し、applicationスコープ、sessionスコープ、requestスコープまたはpageスコープのリソースを管理します。

この機能は、サーブレットとJSP標準に従って、pagerequestsessionまたはapplicationスコープのオブジェクトをサポートします。他のスコープとともにsessionスコープをサポートするクラスを作成するために、クラスにJspScopeListenerインタフェースとHttpSessionBindingListenerインタフェースを実装して、両方のインタフェースを統合できます。OC4J環境でのpageスコープの場合は、Oracle固有の実行時実装を使用することもできます。

HttpSessionBindingListenerの構成と統合方法については、『Oracle Application Server Containers for J2EE JSPタグ・ライブラリおよびユーティリティ・リファレンス』を参照してください。


重要: JspScopeListenerは、OC4J 10.1.2実装では使用できなくなり、今後の実装ではサポートされません。 

実行時エラーの処理

JSPページを実行してクライアント・リクエストを処理している間に、ページの内側または外側(コールされたJavaBean内など)で実行時エラーが発生する場合があります。この項ではエラー処理機能について説明し、基本的な例を示します。

サーブレットとJSPの実行時エラー処理機能

この項では、サーブレット2.3およびJSP 1.2の実行時例外の処理機能について説明します。JSPエラー・ページを使用する場合についても説明します。

一般的なサーブレット実行時エラー処理機能

JSPページの実行中に発生した実行時エラーは、標準のJava例外処理機能によって、次のいずれかの方法で処理されます。

エラー・リソースのURLは、元のJSPページでpageディレクティブのerrorPage属性を設定すると指定できます(pageディレクティブなどのJSPディレクティブの概要は、「ディレクティブ」を参照してください)。

サーブレット2.2以上の環境では、次の命令を使用して、web.xmlデプロイメント・ディスクリプタにデフォルトのエラー・ページを指定することもできます。

<error-page>
   <error-code>404</error-code>
   <location>/error404.html</location>
</error-page>

デフォルトのエラー・リソースの詳細は、Sun社のJavaサーブレット仕様2.3を参照してください。

JSPエラー・ページ

オプションとして、別のJSPページを、元のJSPページからの実行時例外のエラー・リソースとして使用する方法があります。JSPエラー・ページには、isErrorPage="true"に設定するpageディレクティブが必要です。この方法で定義されたエラー・ページは、web.xmlファイルで宣言されているエラー・ページよりも優先されます。

エラーの情報を持つjava.lang.Throwableインスタンスは、エラー・ページでJSPの暗黙的なexceptionオブジェクトを介してアクセス可能です。このオブジェクトにアクセスできるのはエラー・ページのみです。exceptionオブジェクトなど、JSPの暗黙的なオブジェクトの詳細は、「暗黙的なオブジェクト」を参照してください。

元のJSPページにautoFlush="true"(デフォルト設定)のpageディレクティブがあり、そのページのJspWriterオブジェクトのコンテンツがレスポンスの出力ストリームにすでにフラッシュされている場合、取得されなかった例外をエラー・ページに転送しようとしても、レスポンスをクリアできない可能性があることに注意してください。一部のレスポンスは、ブラウザがすでに受信している可能性があります。

エラー・ページの使用例は、次の「JSPエラー・ページの例」の項を参照してください。

JSPエラー・ページの例

次のnullpointer.jspの例では、エラーを生成し、エラー・ページのmyerror.jspを使用して、暗黙的なexceptionオブジェクトのコンテンツを出力します。

nullpointer.jspのコード

<HTML>
<BODY>
<%@ page errorPage="myerror.jsp" %>
Null pointer is generated below:
<%
   String s=null;
   s.length();
%>
</BODY>
</HTML>

myerror.jspのコード

<HTML>
<BODY>
<%@ page isErrorPage="true" %>
Here is your error:
<%= exception %>
</BODY>
</HTML>

この例では、図4-3に示す内容が出力されます。

図4-3    エラー・ページのサンプル


画像の説明


注意: 処理がエラー・ページに転送された場合、nullpointer.jspの「Null pointer is generated below:」の行は出力されません。これは、jsp:include機能とjsp:forward機能の違いを示しています。jsp:forwardの場合は、転送先ページの出力によって、転送元ページの出力が置換されます。 


戻る 次へ
Oracle
Copyright © 2000, 2005 Oracle.

All Rights Reserved.
目次
目次
索引
索引