この章では、データベースを問い合せる機能およびコードをDataHandler.javaファイルに追加します。この章は次の項で構成されています。
JavaクラスからOracle Databaseを問い合せてデータを取得する手順の概要は、次のとおりです。
OracleDataSource.getConnectionメソッドを使用して、接続を作成します。これについては、第3章「Oracle Databaseへの接続」で説明しています。
接続オブジェクトに対して使用可能なメソッドを使用して、SQL文を定義します。SQL問合せ文の定義には、createStatementメソッドを使用します。
文に対して使用可能なメソッドを使用して、問合せを実行します。executeQueryメソッドを使用してデータベースの問合せを実行し、問合せ条件に一致する行のセットを生成します。これらの結果は、ResultSetオブジェクトに含まれます。
ResultSetオブジェクトを使用して、データをアプリケーション・ページに表示します。
次の項では、Javaアプリケーションからのデータベースの問合せに関する主要なJava Database Connectivity(JDBC)の概念について説明します。
|
関連項目: 『Oracle Database JDBC開発者ガイドおよびリファレンス』 |
データベースに接続し、そのプロセスでConnectionオブジェクトを作成した後、次に、Statementオブジェクトを作成します。JDBC ConnectionオブジェクトのcreateStatementメソッドは、JDBC Statement型のオブジェクトを返します。例4-1に、Statementオブジェクトの作成方法を示します。
Statementオブジェクトは、アプリケーション内にコーディングできる静的なSQL問合せを実行するために使用します。
また、更新値を変更しながら、数多くの類似の問合せをデータベースに対して実行する必要がある場合は、Statementオブジェクトを拡張するOraclePreparedStatementオブジェクトを使用します。Oracle Databaseのストアド・プロシージャにアクセスするには、OracleCallableStatementオブジェクトを使用します。
Statementオブジェクトに埋め込まれた問合せを実行するには、executeメソッドのバリアントを使用します。このメソッドの主要なバリアントを表4-1に示します。
表4-1 java.sql.Statementの主要な問合せ実行メソッド
| メソッド名 | 戻り型 | 説明 |
|---|---|---|
|
|
指定されたSQL文を実行します。ブール・レスポンス(問合せが正常に実行された場合はtrue、それ以外はfalse)が戻されます。 |
|
|
|
|
コマンドの |
|
|
コマンドのバッチをデータベースに送信して実行し、すべてのコマンドが正常に実行された場合は、更新件数の配列を戻します。 |
|
|
|
指定されたSQL文を実行します。単一の |
|
|
|
指定されたSQL文を実行します。 |
ResultSetオブジェクトには、データベースの結果セットを表すデータの表が含まれます。この表は、データベースを問い合せる文を実行することによって生成されます。
カーソルが、ResultSetオブジェクト内のデータの現在の行を示します。最初、カーソルは最初の行の前に置かれています。ResultSetオブジェクトのnextメソッドを使用して、カーソルを結果セット内の次の行に移動します。ResultSetオブジェクト内に行がなくなると、falseが戻されます。通常、ResultSetオブジェクトの内容は、ループ内でfalseが戻されるまでnextメソッドを使用して読み取られます。
ResultSetインタフェースには、現在の行から列の値を取得するためのアクセッサ・メソッド(getBoolean、getLong、getIntなど)があります。値は、列の索引番号または列の名前を使用して取得できます。
デフォルトでは、同時に開くことができるのは、Statementオブジェクトごとに1つのResultSetオブジェクトのみです。そのため、複数のResultSetオブジェクトからデータを読み取るには、複数のStatementオブジェクトを使用する必要があります。ResultSetオブジェクトを生成したStatementオブジェクトが閉じられた場合、再実行された場合または複数の一連の結果から次の結果を取得するために使用された場合、そのResultSetオブジェクトは自動的に閉じられます。
|
関連項目:
|
スクロール可能性とは、結果セット内を前後に移動できることをいいます。また、相対位置指定や絶対位置指定によって、結果セット内の任意の位置に移動することもできます。相対位置指定では、現在の行から、指定した行数を前後に移動できます。絶対位置指定では、結果セットの最初または最後から数えて、指定した行番号に移動できます。
スクロール可能または位置指定可能な結果セットを作成するときに、更新検出も指定する必要があります。この機能は、結果セットの外部から基礎となるデータベースに対して行われた変更を検出して示す結果セットの機能のことです。更新検出結果セットでは、結果セットが開かれているときにデータベースに対して行われた変更を知ることができ、基礎となるデータの動的ビューを利用できます。結果セット内の行の基礎となる列の値に対する変更を把握できます。更新可能性とは、結果セット内のデータを更新し、変更をデータベースにコピーできることをいいます。これには、結果セットへの新しい行の挿入や既存の行の削除も含まれます。結果セットは更新可能、または読取り専用です。
スクロール可能性と更新検出は、更新可能性とは無関係であり、3つの結果セット・タイプと2つの同時実行性タイプの組合せで、次の6つの結果セット・カテゴリができます。
転送専用/読取り専用
転送専用/更新可能
スクロール-更新検出/読取り専用
スクロール-更新検出/更新可能
スクロール-非更新検出/読取り専用
スクロール-非更新検出/更新可能
例4-2に、スクロール-更新検出および読取り専用のResultSetオブジェクトを宣言する方法を示します。
例4-2 スクロール-更新検出、読取り専用のResultSetオブジェクトの宣言
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
|
注意: 転送専用の更新可能結果セットでは、ResultSetオブジェクト内の特定の行に位置指定することを想定していません。nextメソッドの使用による行の反復中にのみ、それらの行を更新できます。 |
この項では、JDeveloperを使用してOracle Database内のデータを問い合せるJavaクラスを作成する方法について、次の項で説明します。
次の手順では、簡単な問合せメソッドをDataHandler.javaクラスに追加する方法について説明します。JDeveloper統合開発環境(IDE)でDataHandler.javaが開かれていない場合は、アプリケーション・ナビゲータでダブルクリックして、Javaソース・エディタに表示します。
DataHandlerクラスで、StatementおよびResultSet JDBCクラスを使用するために、次のimport文を既存のimport文の後に追加します。
import java.sql.Statement; import java.sql.ResultSet;
connection宣言の後、次のようにStatement、ResultSetおよびStringオブジェクトの変数を宣言します。
Statement stmt; ResultSet rset; String query; String sqlString;
データベースから従業員情報を取得するgetAllEmployeesという名前のメソッドを作成します。メソッドのシグネチャを入力します。
public ResultSet getAllEmployees() throws SQLException{
[Enter]を押して、このメソッドの閉じカッコ、およびメソッド・コードの入力を開始する新しい行を挿入します。
以前に作成したgetDBConnectionメソッドをコールします。
getDBConnection();
ConnectionインスタンスのcreateStatementメソッドを使用して、SQL文を実行するコンテキストを指定し、ResultSetタイプを定義します。読取り専用、スクロール-更新検出ResultSetタイプを指定します。
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
Javaコード・インサイト機能によって、文の構文が正しいことを確認できます。
問合せを定義し、トレース・メッセージを出力します。次のコードでは、簡単な問合せが使用されており、Employees表のすべての行を列が戻され、データは従業員ID順に並べられます。
query = "SELECT * FROM Employees ORDER BY employee_id";
System.out.println("\nExecuting query: " + query);
次のように、問合せを実行して結果をResultSetインスタンスに取得します。
rset = stmt.executeQuery(query);
ResultSetオブジェクトを戻します。
return rset;
作業内容を保存します。「ファイル」メニューで、「すべて保存」を選択します。
getAllEmployeesメソッドのコードは、例4-3に示すようになります。
例4-3 Connection、Statement、QueryおよびResultSetオブジェクトの使用
public ResultSet getAllEmployees() throws SQLException{
getDBConnection();
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
query = "SELECT * FROM Employees ORDER BY employee_id";
System.out.println("\nExecuting query: " + query);
rset = stmt.executeQuery(query);
return rset;
}
次の手順では、簡単なJavaクラスを作成し、DataHandler.javaクラスのメソッドをテストします。この段階でアプリケーションをテストするため、一時的にjdbcUrl変数の値をデータベースの接続文字列に設定し、useridおよびpassword変数の値をHRスキーマへのアクセスに必要な値(いずれの場合もhr)に設定します。
アプリケーション・ナビゲータから、Javaビジュアル・エディタでDataHandler.javaクラスを開きます。
次のように、HRスキーマに必要な値を含むように、jdbcUrl、 useridおよびpassword変数を変更します。
String jdbcUrl = "connect-string"
String userid = "hr";
String password = "hr";
connect-stringの例は、次のとおりです。
jdbc:oracle:thin:@dbhost.companyname.com:1521:ORCL
hrパッケージ内に新しいJavaクラスを作成します。このJavaクラスにJavaClientという名前を付け、publicクラスにし、デフォルトのコンストラクタおよびmainメソッドを生成します。スケルトンJavaClient.javaクラスが作成され、Javaソース・エディタに表示されます。
ResultSetパッケージをインポートします。
import java.sql.ResultSet;
mainメソッド宣言で、次のように例外処理を追加します。
public static void main(String[] args) throws Exception{
デフォルトで作成されたJavaClientオブジェクトをDataHandlerオブジェクトで置き換えます。次の行を見つけます。
JavaClient javaClient = new JavaClient();
これを次のように置き換えます。
DataHandler datahandler = new DataHandler();
getAllEmployees問合せの結果を保持するようにResultSetオブジェクトを定義し、結果セットの行を反復して最初の4つの列Employee Id、First Name、Last NameおよびEmailを表示します。このことを行うには、次のコードをmainメソッドに追加します。
ResultSet rset = datahandler.getAllEmployees();
while (rset.next()) {
System.out.println(rset.getInt(1) + " " +
rset.getString(2) + " " +
rset.getString(3) + " " +
rset.getString(4));
}
JavaClient.javaファイルをコンパイルし、コンパイル・エラーをチェックします。このことを行うには、Javaソース・エディタで右クリックし、ショートカット・メニューで「メイク」を選択します。
コンパイルでエラーがない場合は、次のメッセージがログ・ウィンドウに表示されます。
コンパイルが成功しました: 0件のエラー、0件の警告
JavaClient.javaファイルを実行します。このことを行うには、Javaソース・エディタのウィンドウで右クリックし、ショートカット・メニューで「実行」を選択します。
ログ・ウィンドウで出力を確認します。図4-1に示すようトレース・メッセージが表示され、その後、Employees表からの4つの列が表示されます。
アプリケーションのテストが終了したら、DataHandler.javaのjdbcUrl、useridおよびpassword変数をnullに戻します。
HRAppアプリケーションでは、JavaServer Pages(JSP)テクノロジを使用してデータを表示します。JSPテクノロジによって、サーバーおよびプラットフォームに依存しない動的なWebコンテンツを簡単かつ迅速に作成できます。JSPページには、.jsp拡張子が付きます。この拡張子によって、ページをJSPコンテナで処理する必要があることがWebサーバーに指定されます。JSPコンテナによって、JSPタグおよびスクリプトレットが解析され、必要なコンテンツが生成され、結果がHTMLまたはXMLページとしてクライアントに戻されます。
JSPページを開発するには、次の項目の一部またはすべてを使用します。
この項では、このマニュアルのアプリケーションのJSPページを作成する方法について説明します。
このマニュアルで作成するアプリケーションでは、次の処理を行うためにJSPページが使用されます。
データを表示します。
従業員の追加および従業員データの編集を行うユーザーが入力した入力データを保持します。
ユーザー資格証明の検証およびデータベース内の従業員レコードの追加、更新および削除のアクションを処理するために必要なコードを保持します。
JSPページはHTMLまたはXMLとしてユーザーに表示されるので、静的HTMLおよびXMLページの場合と同じようにデータの表示を制御できます。ページのタイトルを表示するときにヘッダーで指定するtitleタグなど、標準のHTMLタグを使用してページの書式を設定できます。
ページ上の見出し、表、リストなどの項目にHTMLタグを使用します。スタイルシートを使用して項目の表示を定義することもできます。JDeveloperを使用してアプリケーションを開発する場合、リストからスタイルを選択できます。
次の項では、サンプル・アプリケーションのJSPページで使用される主な要素について説明します。
このマニュアルのサンプル・アプリケーションでは、JSPタグが使用されています。単一の従業員レコードを保持するために使用されるアプリケーション・メソッドとJavaBeanを保持するJavaクラスを初期化するため、およびアプリケーション内の同じページまたは別のページにユーザーを転送するためです。
ページでは、jsp:useBeanタグを使用して、アプリケーションに必要なすべてのメソッドを含むクラスを初期化し、jsp:forwardタグを使用して、指定されたページにユーザーを転送します。JSPタグのコンポーネント・パレットから必要なタグをドラッグし、表示された対応するダイアログ・ボックスでタグのプロパティを入力できます。
スクリプトレットは、データベースに対して作用するJavaメソッドを実行する場合や、JSPページでその他の処理を実行する場合に使用します。scriptletタグ・コンポーネントをコンポーネント・パレットからページにドラッグ・アンド・ドロップすると、スクリプトレット・コードを入力する準備が整います。JDeveloperでは、スクリプトレットのコードはスクリプトレット・ソース・エディタ・ダイアログ・ボックスに入力します。
このアプリケーションでは、様々なタスクでスクリプトレットを使用します。たとえば、あるスクリプトレットがコールするDataHandlerメソッドは、Employees表内のすべての従業員が含まれているResultSetオブジェクトを返します。このオブジェクトを使用してJSPページにデータを表示できます。同じResultSetオブジェクトを反復処理して表の行の各項目を表示するためにスクリプトレットを使用する例もあります。
通常HTMLタグは、見出しや表など、ユーザー・インタフェースの非動的部分のレイアウトや表示に使用されます。JDeveloperでは、「表」コンポーネントをコンポーネント・パレットからページにドラッグ・アンド・ドロップできます。表の列数と行数を指定すると、すべてのtableタグが自動的に作成されます。
HTMLフォームは、Webページ上で、ユーザーとの相互作用またはユーザーからの情報の収集に使用されます。FORM要素は、ページ上のコントロールのコンテナとして機能し、フォーム入力の処理に使用されるメソッドを指定します。
表示する従業員を選択するフィルタ・コントロールの場合、employees.jspページ自体がフォームを処理します。ログイン、挿入、編集および削除処理の場合、これらのフォームを処理するために追加のJSPページが作成されます。このアプリケーションのJSPページの相互関係については、図1-2を参照してください。
JSPページでフォームを追加するには、HTMLタグのコンポーネント・パレットからフォームを選択します。ページのフォーム・コンポーネントの外側またはフォームが含まれていないページでコントロールを追加しようとすると、JDeveloperによって、そのコントロールを格納するフォーム・コンポーネントを追加するように求められます。
次の手順では、簡単なJSPページを作成する方法について説明します。
アプリケーション・ナビゲータで、Viewプロジェクトを右クリックし、ショートカット・メニューで「新規」を選択します。
「新規ギャラリ」で、「すべてのテクノロジ」タブを選択します。
「カテゴリ」リストで「Web層」ノードを開き、「JSP」を選択します。
「項目」リストで、「JSP」を選択し、「OK」をクリックします。「JSPの作成」ダイアログ・ボックスが表示されます。
「JSPファイル」画面で、JSPページの名前を入力し、「JSPページ」を選択します。
「JSPの作成」画面で、JSPページの名前を入力し、「OK」を選択します。JSP/HTMLビジュアル・エディタに新しいページが開き、テキストおよびコンポーネントをWebページに追加できるようになります。
JDeveloperには、JSP/HTMLビジュアル・エディタの右側に、コンポーネント・パレットとプロパティ・インスペクタがあります。ページ下部の「設計」タブの隣にあるソース・エディタタブをクリックして、JSPソース・エディタを使用することもできます。コンポーネント・パレットではコンポーネントをページに追加でき、プロパティ・インスペクタではコンポーネントのプロパティを設定できます。図4-2に、ビジュアル・エディタの空白ページを示します。
図4-2 JDeveloperのビジュアル・ソース・エディタでのJSPページへのコンテンツの追加

次の手順では、employees.jspページにテキストを追加する方法について説明します。ビジュアル・エディタを使用してJSPを変更します。ビジュアル・エディタはWYSIWYGエディタのようなものであり、これを使用してコンテンツを変更できます。
employees.jspがビジュアル・エディタで開かれている状態で、ページの一番上の行に、AnyCo Corporation: HR Applicationと入力します。ページの一番上にある左側のスタイルのリストから、Heading 2を選択します。
追加した見出しにカーソルを置いたまま、「設計」メニューから「位置」を選択し、次に、「中央揃え」を選択します。
同様に、新しい行でEmployee Dataと入力し、Heading 3スタイルで書式設定します。ページの左側に配置します。
見出し、テキストなどの要素がWebページで使用されるフォントや色などの表示特性と調和して書式設定されるように、スタイルシート参照をページに追加できます。次のように、スタイルシートをページに追加できます。
employees.jspがビジュアル・エディタで開かれている状態で、コンポーネント・パレットの右上にあるリスト矢印をクリックして、「CSS」を選択します。
「CSS」リストから、「JDeveloper」をページにドラッグします。選択したスタイルシートはすぐにページに追加され、JDeveloper形式でページが書式設定されます。図4-3に、前述の項でコンテンツが追加されたJSPページと、そのページに適用されたJDeveloperスタイルシートを示します。
|
注意: JDeveloperバージョン10.1.3では、JSPの作成ウィザードでのJSPページの作成中に、スタイルシートをJSPページに関連付けることができます。ただし、ページにドラッグ・アンド・ドロップするのではなく、JSPページに適用するスタイルシートを参照して見つける必要がある点のみ異なります。 |
この項では、次の項目について説明します。
jsp:useBeanタグによって、ページで実行されるメソッドを保持するクラスが識別および初期化されます。jsp:useBeanタグを追加するには、次の手順を実行します。
ビジュアル・エディタでemployees.jspを開きます。
コンポーネント・パレットで、コンポーネントの「JSP」セットを選択します。リストをスクロールして、「UseBean」を選択します。次に、それをJSPページの見出しの下にドラッグ・アンド・ドロップします。
「UseBeanの挿入」ダイアログ・ボックスで、empsbeanを「ID」として入力し、「クラス」にはhr.DataHandlerクラスを参照して選択します。「有効範囲」を「セッション」に設定し、「タイプ」および「Bean名」フィールドは空白のままにします。
「OK」をクリックして、ページにタグを作成します。
図4-4に、employees.jspページのuseBeanタグの表示を示します。
次の手順では、スクリプト要素をページに追加してgetAllEmployeesメソッドをコールし、戻された結果セット・データを保持する方法について説明します。この問合せは、DataHandlerクラスで定義され、jsp:useBeanタグを使用してページで初期化されます。
ビジュアル・エディタでemployees.jspページを開きます。コンポーネント・パレットの「JSP」部分で、「スクリプトレット」を選択して、JSPページのUseBeanの表示の横にドラッグ・アンド・ドロップします。
「スクリプトレットの挿入」ダイアログ・ボックスで、次のコード行を入力します。このコード行はgetAllEmployeesメソッドをコールし、ResultSetオブジェクトを生成します。
ResultSet rset; rset = empsbean.getAllEmployees();
「OK」をクリックします。スクリプトレットの表示は、図4-5に示すようにページに表示されます。
ビジュアル・エディタの一番下にある「ソース」タブを選択して、ページに対してこれまでに作成されたコードを表示します。ResultSetの下の波線は、コードにエラーがあることを示しています。
左側の構造ウィンドウでも、ページにエラーがあることを示しています。ウィンドウの最上部までスクロールして、「JSPエラー」ノードを開きます。図4-6に、コード内のエラーが構造ウィンドウでどのように表示されるかを示します。
ResultSetパッケージをインポートする必要があります。このことを行うには、構造ウィンドウで「ページ」ノードをクリックして、プロパティ・インスペクタでページのプロパティを表示します。
「インポート」プロパティの右の空のボックスをクリックします。省略記号(...)をクリックします。図4-7に示すように、「インポート」ダイアログ・ボックスが表示されます。
インポート・リストで、「階層」タブを選択し、「java」ノード、「sql」ノードの順に開き、ResultSetを選択します。「OK」をクリックします。
「ソース」タブで、import文がページのコードに追加されているかどうかを確認します。構造ウィンドウのリストからエラーが消えています。次の項に進む前に、「設計」タブを選択してこのページの設計ビューに戻ります。
次の手順では、JSPページに表を追加して、getAllEmployees問合せの結果を表示する方法について説明します。
employees.jspページがビジュアル・エディタで開かれていない場合は、アプリケーション・ナビゲータでダブルクリックして開き、「設計」タブで作業します。employees.jspファイルがビジュアル・エディタで開かれている状態で、カーソルをスクリプトレットの後に置き、コンポーネント・パレットの「HTML Common」ページから、「表」コンポーネントを選択します。
「表の挿入」ダイアログ・ボックスで、1行および6列を指定します。すべてのレイアウト・プロパティをデフォルトのままにします。「OK」をクリックします。
ページに表示された表の行で、各列の見出しとしてFirst Name、Last Name、Email、Job、PhoneおよびSalaryと入力します。Heading 4を使用して列名の書式を設定します。
表内の各列に対して返される値を表示するための、出力用スクリプト要素を追加します。これを行うには、次のように表を選択します。表の上部境界線上にカーソルを移動し、カーソル・イメージが表のイメージに変わったところでクリックします。JSPコンポーネント・パレットで、スクリプトレットを選択します。(表にドラッグしなくても、スクリプトレットが自動的に挿入されます。)
「スクリプトレットの挿入」ダイアログ・ボックスで、次のコード行を入力します。
while (rset.next ())
{
out.println("<tr>");
out.println("<td>" +
rset.getString("first_name") + "</td><td> " +
rset.getString("last_name") + "</td><td> " +
rset.getString("email") + "</td><td> " +
rset.getString("job_id") + "</td><td>" +
rset.getString("phone_number") + "</td><td>" +
rset.getDouble("salary") + "</td>");
out.println("</tr>");
}
「OK」をクリックします。
図4-8に、作成されたJSPページを示します。
特定のパラメータまたは条件で問合せの結果をフィルタできます。アプリケーションのユーザーがデータ・フィルタをカスタマイズできるようにすることもできます。このマニュアルで作成するサンプル・アプリケーションでは、次の手順で問合せ結果をフィルタします。
必要なフィルタ・セットの判別
問合せフィールドにフィルタ基準(この場合、検索する名前の一部)を入力することにより、ユーザーは表示する従業員レコードのセットを指定できます。employees.jspページは、フォーム・コントロールをとおしてこの入力を受け付け処理します。
問合せのResultSetを戻すメソッドの作成
SQL問合せ文の作成に、ユーザー入力文字列を使用します。この文によって、ユーザーが入力した文字列が名前に含まれるすべての従業員が選択されます。問合せでは、姓と名の両方でこの文字列が検索されます。
問合せの結果の表示
このことは、employees.jspページにコードを追加して、フィルタされる問合せを実行するメソッドを使用することによって実行されます。
この項では、問合せデータのフィルタについて、次の項で説明します。
次の手順では、getEmployeesByNameメソッドを作成する方法について説明します。このメソッドによって、ユーザーは従業員を姓または名でフィルタできます。
getAllEmployeesメソッドの後に、次のようにgetEmployeesByNameメソッドを宣言します。
public ResultSet getEmployeesByName(String name) throws SQLException {
}
メソッド本体で次のコードを追加し、検索ヒット数が増えるように、名前を大文字に変換します。
name = name.toUpperCase();
データベースに接続するメソッドをコールします。
getDBConnection();
ResultSetタイプを指定し、問合せを作成します。
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
query =
"SELECT * FROM Employees WHERE UPPER(first_name) LIKE \'%" + name + "%\'" +
" OR UPPER(last_name) LIKE \'%" + name + "%\' ORDER BY employee_id";
トレース・メッセージを出力します。
System.out.println("\nExecuting query: " + query);
問合せを実行し、以前と同様に結果セットを戻します。
rset = stmt.executeQuery(query); return rset;
ファイルを保存し、コンパイルしてコンパイル・エラーがないことを確認します。
「接続メソッドおよび問合せメソッドのテスト」で作成したJavaClient.javaクラスを使用して、getEmployeesByNameメソッドをテストできます。次の手順で説明するように、getEmployeesByNameメソッドを追加して問合せ結果を表示する必要があります。
Javaソース・エディタでJavaClient.javaクラスを開きます。
結果セットにgetAllEmployees問合せからの結果が表示された後、次のように条件問合せの結果セットを定義します。
rset = datahandler.getEmployeesByName("King");
System.out.println("\nResults from query: ");
while (rset.next()) {
System.out.println(rset.getInt(1) + " " +
rset.getString(2) + " " +
rset.getString(3) + " " +
rset.getString(4));
}
この段階でアプリケーションをテストするため、一時的にDataHandlerクラスのjdbcUrl、useridおよびpassword変数値を調節して、HRスキーマに必要な値を指定します。ファイルを保存し、コンパイルして構文エラーをチェックします。
コードをテスト実行するには、Javaソース・エディタで右クリックし、ショートカット・メニューで「実行」を選択します。ログ・ウィンドウには、最初にgetAllEmployeesメソッドの結果が表示され、次に、getEmployeesByName("xxx")問合せの結果が表示されます。ここでは、xxxを「King」に設定して、フィルタ機能をテストしています。実際の操作では、このパラメータはアプリケーションのユーザーが指定した値に設定され、検索がフィルタされます。
フィルタ基準を受け入れてフィルタ結果を表示するには、employees.jspページを変更する必要があります。次の手順では、ユーザーからの入力を受け入れるemployees.jspページにフォーム要素およびコントロールを追加して、従業員を名前でフィルタします。
employees.jspページがビジュアル・エディタに表示されている状態で、カーソルをuseBeanタグとスクリプトレットの間に置きます。
コンポーネント・パレットの「HTML Forms」ページで、「フォーム」を選択します。
「フォームの挿入」ダイアログ・ボックスで、「アクション」フィールドの下矢印を使用して、employees.jspを選択します。他のフィールドは空のままにし、「OK」をクリックします。
フォームがビジュアル・エディタのページに表示され、点線の四角形で表されます。
コンポーネント・パレットの「HTML Forms」ページで、「テキスト・フィールド」にスクロールします。それを選択し、フォーム・コンポーネント内にドラッグ・アンド・ドロップします。「テキスト・フィールドの挿入」ダイアログ・ボックスで、「名前」フィールドの値としてqueryと入力し、「OK」をクリックします。フォーム内にテキスト・フィールド・ボックスが表示されます。ユーザーはこのフィールドにフィルタ基準を入力できます。
テキスト・フィールドの左にカーソルを置き、次のテキストを追加します。
Filter by Employee name:
コンポーネント・パレットの「HTML Forms」ページで、「Submit Button」にスクロールします。それを選択し、フォーム・コンポーネント内のテキスト・フィールドの右にドラッグします。
「送信ボタンの挿入」ダイアログ・ボックスで、「名前」フィールドは空のままで「値」フィールドの値としてFilterと入力し、「OK」をクリックします。
図4-9に、employees.jspファイルのこれらのHTMLフォーム・コンポーネントを示します。
前の項で、ユーザー入力を受け入れるテキスト・フィールド・コンポーネントをJSPページに作成しました。このテキスト・フィールドで、ユーザーは従業員の名前をフィルタするために使用する文字列を指定できます。また、送信ボタンも追加しました。
次の手順では、employees.javaファイル内のスクリプトレットにコードを追加して、getEmployeesByNameメソッドを使用できるようにします。このメソッドは、結果をフィルタするための値をユーザーが送信した場合にのみ使用されます。このフィルタ基準を指定しない場合は、getAllEmployeesメソッドが使用されます。
ビジュアル・エディタでemployees.jspファイルを開きます。
ページのスクリプトレット・タグ(表内ではありません)をダブルクリックして、「プロパティ」ダイアログ・ボックスを開きます。次のようにコードを変更します。
ResultSet rset;
String query = request.getParameter("query");
if (query != null && query != null)
rset = empsbean.getEmployeesByName(query);
else
rset = empsbean.getAllEmployees();
図4-10に、「スクリプトレットのプロパティ」ダイアログ・ボックスを使用してコードを変更する方法を示します。
「OK」をクリックします。
ファイルを保存します。
サンプル・アプリケーションで使用されるログイン機能は、アプリケーション管理セキュリティの簡単な例です。完全なJava EEセキュリティ実装ではありませんが、サンプル・アプリケーションでの例として使用されます。
この簡単なログイン機能を実装するには、次の処理を実行する必要があります。
次の手順では、DataHandler.javaクラスにメソッドを作成します。このメソッドでは、useridおよびpasswordに対して入力された値と、データベース・スキーマが必要とする値が一致するかどうかをチェックすることによってユーザーを認証します。
ソース・エディタでDataHandler.javaクラスを開きます。
ユーザーが入力したuserid、passwordおよびhostの値が有効かどうかをチェックするauthenticateUserという名前のメソッドを作成します。
public boolean authenticateUser(String jdbcUrl, String userid, String password,
HttpSession session) throws SQLException {
}
波線の下線とHttpSessionのクラスをインポートする必要があるというメッセージが表示されます。[Alt]キーを押しながら[Enter]キーを押して、javax.servlet.http.HttpSessionクラスをインポートします。
メソッド本体で、次のようにコールのjdbcUrl、useridおよびpassword値を現在のオブジェクトの属性に割り当てます。
this.jdbcUrl= jdbcUrl; this.userid = userid; this.password = password;
指定された値を使用してデータベースへの接続を試行し、成功した場合は値trueを返します。これを次のようにtryブロックで囲みます。
try {
OracleDataSource ds;
ds = new OracleDataSource();
ds.setURL(jdbcUrl);
conn = ds.getConnection(userid, password);
return true;
}
ログイン資格証明が一致しない場合を処理するには、tryブロックの後にcatchブロックを追加します。このブロックのコードでは、ログ・メッセージを出力し、エラー・メッセージを設定します。このエラー・メッセージは、ログイン試行が失敗した場合にユーザーに表示されます。jdbcUrl、useridおよびpassword変数はnullに戻され、メソッドは値falseを戻します。このことを行うには、次のコードを入力します。
catch ( SQLException ex ) {
System.out.println("Invalid user credentials");
session.setAttribute("loginerrormsg", "Invalid Login. Try Again...");
this.jdbcUrl = null;
this.userid = null;
this.password = null;
return false;
}
例4-4に、完成したコードを示します。
例4-4 ユーザー検証の実装
public boolean authenticateUser(String jdbcUrl, String userid, String password,
HttpSession session) throws SQLException {
this.jdbcUrl = jdbcUrl;
this.userid = userid;
this.password = password;
try {
OracleDataSource ds;
ds = new OracleDataSource();
ds.setURL(jdbcUrl);
conn = ds.getConnection(userid, password);
return true;
} catch ( SQLException ex ) {
System.out.println("Invalid user credentials");
session.setAttribute("loginerrormsg", "Invalid Login. Try Again...");
this.jdbcUrl = null;
this.userid = null;
this.password = null;
return false;
}
}
次の手順では、login.jspページを作成します。このページで、ユーザーは作業を行うスキーマのログイン詳細を入力します。
Viewプロジェクトで、新しいJSPページを作成します。名前をlogin.jspに変更し、その他はすべてデフォルトをそのまま使用します。JSP/HTMLビジュアル・エディタで新しいページが開き、テキストおよびコンポーネントをWebページに追加できるようになります。
JDeveloperスタイルシートをページに適用します。
このページに、以前に設定したものと同じ見出しAnyCo Corporation: HR Applicationを付け、Heading 2スタイルを割り当て、ページの中央に配置します。
次の行で、Application Loginと入力し、Heading 3スタイルを適用します。この見出しをページの左側に配置します。
次の手順では、ユーザー・ログインが失敗したときにエラー・メッセージを表示する機能をlogin.jspページに追加します。login.jspページで使用されるスクリプトレットおよび式によって、エラー・メッセージを保持する変数が設定されます。ユーザー・ログインが失敗した場合、接続メソッドによってセッションのメッセージが設定されます。このページではそのようなメッセージがあるかどうかをチェックし、存在する場合にはメッセージを表示します。
login.jspページがビジュアル・エディタで開かれている状態で、カーソルをこのページのテキストの後に置きます。次に、コンポーネント・パレットの「JSP」ページから、「スクリプトレット」要素をパレットからページにドラッグ・アンド・ドロップします。
「スクリプトレットの挿入」ダイアログ・ボックスで、次のコードを入力します。
String loginerrormsg = null;
loginerrormsg = (String) session.getAttribute("loginerrormsg");
if (loginerrormsg != null) {
別のスクリプトレットを同じ方法で追加し、今度は1つの閉じカッコ(})のみを「スクリプトレットの挿入」ダイアログ・ボックスで入力します。
2つのスクリプトレットの間にカーソルを置き、[Enter]を押して新しい行を作成します。新しい行にHeading 4スタイルを適用します。
カーソルを新しい行に置いたまま、コンポーネント・パレットの「JSP」ページで、「式」をクリックします。
「式の挿入」ダイアログ・ボックスで、loginerrormsgと入力します。
login.jspページに追加されたコードを表示するには、ビジュアル・エディタの下の「ソース」タブを選択します。コードは次のように表示されます。
<%
String loginerrormsg = null;
loginerrormsg = (String) session.getAttribute("loginerrormsg");
if (loginerrormsg != null) {
%>
<h4>
<%= loginerrormsg %>
</h4>
<%
}
%>
次の項に進む前に、「設計」タブを選択してこのページの設計ビューに戻ります。
これらの手順では、ユーザーがログイン詳細を入力するフィールドをlogin.jspページに追加します。
login.jspページがビジュアル・エディタで開かれていない場合は、アプリケーション・ナビゲータでダブルクリックして開き、「設計」タブが選択されていることを確認します。
カーソルを2番目のスクリプトレットの後に置き、コンポーネント・パレットの「HTML Forms」ページで、「フォーム」を選択します。フォームがビジュアル・エディタのページに表示され、点線の四角形で表されます。
コンポーネント・パレットの「HTML Forms」ページで、「フォーム」を選択します。「フォームの挿入」ダイアログ・ボックスで、「アクション」フィールドの値としてlogin_action.jspと入力します。このファイルは、login.jspファイルでのユーザー入力を処理するために使用されます。(このページはまだ作成されていないため、リストから選択できません。)他のフィールドは空のままにし、「OK」をクリックします。
フォームがビジュアル・エディタのページに表示され、点線の四角形で表されます。
表をページに追加します。フォーム内に配置します。3行および2列のレイアウトを指定し、その他のレイアウトのデフォルトはそのまま使用します。
3行の最初の列に、ユーザーに表示するテキストとして次のように入力します。
User ID:
Password:
Host:
コンポーネント・パレットの「HTML」ページから、「テキスト・フィールド」をUser ID:セルの右のセルにドラッグします。「テキスト・フィールドの挿入」ダイアログ・ボックスで、Nameプロパティの値としてuseridと入力します。他のフィールドは空のままにし、「OK」をクリックします。
同じ方法で、「テキスト・フィールド」をPassword:セルの右のセルに追加し、「名前」プロパティの値としてpasswordと入力します。同様に、「テキスト・フィールド」をHost:セルの右のセルに追加し、「名前」プロパティの値としてhostと入力します。
「発行」ボタンを表の下のフォームにドラッグします。ボタンの「値」プロパティにSubmitと入力します。
4-11に示すようにlogin.jspページが表示されます。
次の手順では、login_action.jspページを作成します。これは、ログイン操作を処理する非表示のページです。
JSPページを作成し、login_action.jspという名前を付けます。JSPページのすべてのデフォルト設定をそのまま使用します。
login_action.jspがビジュアル・エディタで開かれている状態で、コンポーネント・パレットの「JSP」ページから、Page Directiveコンポーネントをページにドラッグします。「Page Directiveの挿入」ダイアログ・ボックスの「インポート」フィールドで、java.sql.ResultSetをインポートするために参照します。「OK」をクリックします。
jsp:usebeanタグをページにドラッグします。empsbeanをIDとして入力し、hr.DataHandlerをクラスとして参照して選択します。「有効範囲」を「セッション」に設定し、「OK」をクリックします。
カーソルをuseBeanタグの後に置き、スクリプトレットをページに追加します。次のコードを「スクリプトレットの挿入」ダイアログ・ボックスに入力し、「OK」をクリックします。
boolean userIsValid = false;
String host = request.getParameter("host");
String userid = request.getParameter("userid");
String password = request.getParameter("password");
String jdbcUrl = "jdbc:oracle:thin:@" + host + ":1521:ORCL";
userIsValid = empsbean.authenticateUser(jdbcUrl, userid, password, session);
別のスクリプトレットを追加し、次のコードを追加します。
if (userIsValid){
コンポーネント・パレットの「JSP」ページで、Forwardを見つけてページにドラッグし、jsp:forwardタグをページに追加します。「Forwardの挿入」ダイアログ・ボックスで、employees.jspと入力します。
別のスクリプトレットを追加し、次のコードを入力します。
} else {
別のjsp:forwardタグを追加し、今度はlogin.jspに移動します。
最後のスクリプトレットを追加し、閉じカッコ(})を入力します。
作業内容を保存します。
login_action.jspに追加されたコードを表示するには、「ソース」タブを選択します。次のようなコードが表示されます。
<body>
<%@ page import="java.sql.ResultSet"%><jsp:useBean id="empsbean"
class="hr.DataHandler"
scope="session"/>
<%boolean userIsValid = false;
String host = request.getParameter("host");
String userid = request.getParameter("userid");
String password = request.getParameter("password");
String jdbcUrl = "jdbc:oracle:thin:@" + host + ":1521:ORCL";
userIsValid = empsbean.authenticateUser(jdbcUrl, userid, password, session);%><%if (userIsValid){%><jsp:forward page="employees.jsp"/><%if (userIsValid){%><jsp:forward page="login.jsp"/><%}%>
</body>
ログイン・ページと従業員のフィルタをテストするには、次の手順を実行します。
アプリケーション・ナビゲータで、Viewプロジェクトを右クリックし、「実行」を選択します。
プロジェクトのデフォルトの実行ターゲットの指定を求められる場合があります。ここでは、実行ターゲットにlogin.jspを設定します。後でプロジェクトのプロパティを変更して、デフォルトの実行ターゲット・ページを任意のページにすることができます。
図4-12に示すように、ログイン・ページがブラウザに表示されます。
データベースについて次のログイン詳細を入力し、「発行」をクリックします。
User ID: hr
Password: hr
Host: Oracle Databaseが存在するマシンのホスト名
図4-13に示すように、Employee.javaファイルがブラウザに表示されます。
従業員データをフィルタする文字列を入力します。たとえば、「Filter by Employee Name」フィールドにingと入力し、「Filter」をクリックします。次に示すように、フィルタされたリストが表示されます。