Oracle Application Server アプリケーション開発者ガイド 10gリリース2(10.1.2) B15629-01 |
|
ここまでの章では、JSPクライアント・ファイルとビジネス・ロジック・オブジェクトについて説明してきました。この章では、これらのオブジェクト間の相互作用、すなわち、JSPファイルがオブジェクトにアクセスし、それらのオブジェクトからデータを取得する方法について説明します。
この章の項目は次のとおりです。
ビジネス層オブジェクトのメソッドの中には、パブリックとして宣言されるものがありますが、クライアント層オブジェクト(すなわち、JSPファイル)は、これらのオブジェクトおよびメソッドの一部にのみアクセスします。これらのメソッドは、他のビジネス層オブジェクトから起動できるように、パブリックとして宣言されます。
JSPファイルからは、Employee
BeanまたはBenefitCatalog
Beanのメソッドを直接起動しません。そのかわりに、JSPファイルからEmployeeManager
Beanのメソッドを起動して、それらのメソッドから、Employee
オブジェクトまたはBenefitCatalog
オブジェクトのメソッドを起動します。EmployeeManager
クラスには、ビジネス・ロジック処理を実行するメソッドがあります。
EmployeeManager
Beanの参照を取得するには、JSPファイルから、通常のJavaクラスであるSessionHelper
クラスを参照します。SessionHelper
クラスには、getEmployeeManager
というstaticメソッドが含まれ、このメソッドによって、EmployeeManager
のインスタンスが戻されます。SessionHelper
クラスによって、Session Beanがインスタンス化されてHttpSession
クラスの属性に格納されます。次に、例を示します。
// from addBenefitToEmployee.jsp <% int empId = Integer.parseInt(request.getParameter( SessionHelper.EMP_ID_PARAMETER)); EmployeeManager mgr = SessionHelper.getEmployeeManager(request); Collection unelected = mgr.getUnelectedBenefitItems(empId); ... %>
一般的に、ユーザーは外部ページのリンクを介してアプリケーションにアクセスします。リンクのURLは、次のように表示されます。
http://<host>/empbft/controller?action=queryEmployee
ユーザーがアクセスすると、ID入力ページ(図3-1)が表示されます。
図6-1は、問合せ処理のフローを図で示したものです。図中の番号は、図の後に説明している手順の番号に対応しています。この図は、ブラウザからのリクエストのみを示しています。
B1: アプリケーションへのリクエストは、コントローラ・サーブレットによって処理されます。
B2: action
パラメータの値はqueryEmployee
です。したがって、コントローラは、QueryEmployee
クラスのperformAction
メソッドを起動します。
B3: リクエストは、performAction
メソッドによって、queryEmployee.jsp
ファイルに転送されます。これによって、ID入力ページ(図3-1)が表示されます。
B4: ユーザーは従業員IDを入力し、「Query Employee」ボタンをクリックします。リクエストには、action
パラメータと同じ値(queryEmployee
)がまだ含まれますが、従業員IDパラメータも含まれています。リクエストは、再びQueryEmployee
クラスによって処理されます。
B5: QueryEmployee
クラスのperformAction
メソッドおよびqueryEmployee.jsp
ファイルによって、ユーザーが入力した従業員IDが有効であるかどうかが確認されます。
B6: 従業員IDが有効な場合は、JSPファイルを使用して、データベースへの問合せを実行し、指定された従業員IDのデータを取得します。
従業員の詳細情報を取得するには、queryEmployee.jsp
を使用して、EmployeeManager
のgetEmployeeDetails(employeeId)
メソッドを起動します。このメソッドによって、従業員のデータを含むEmployeeModel
オブジェクトが戻されます。次に、JSPを使用して、EmployeeModel
オブジェクトから値を取得して、従業員データを表示します。
// from queryEmployee.jsp <% ... int id = Integer.parseInt(empId); EmployeeManager mgr = SessionHelper.getEmployeeManager(request); EmployeeModel emp = mgr.getEmployeeDetails(id); ... %> ... <h4>Employee Details</h4> <table> <tr><td>Employee ID: </td><td colspan=3><b><%=id%></b></td></tr> <tr><td>First Name: </td><td><b><%=emp.getFirstName()%></b></td><td>Last Name: </td><td><b><%=emp.getLastName()%></b></td></tr> <tr><td>Email: </td><td><b><%=emp.getEmail()%></b></td><td>Phone Number: </td><td><b><%=emp.getPhoneNumber()%></b></td></tr> <tr><td>Hire Date: </td><td><b><%=emp.getHireDate().toString()%></b></td><td>Job: </td><td><b><%=emp.getJobId()%></b></td></tr> </table>
EmployeeManager
のgetEmployeeDetails
メソッドによって、次の処理が開始されます。
getEmployee
をコールして、目的の従業員のインスタンスを取得します。
getEmployee
は、Employee
クラスのfindByPrimaryKey
を起動します。これによって、EmployeeBean
のejbFindByPrimaryKey
をコールします。
ejbFindByPrimaryKey
は、EmployeeDAOImpl
のfindByPrimaryKey
をコールします。すると、int型が戻されます。
findByPrimaryKey
からEmployee
Beanを戻すことができます。
Employee
クラスのfindByPrimaryKey
は、特別なメソッドであることに注意してください。このメソッドを起動すると、EJBコンテナによって、ejbLoad
が自動的にコールされます。ejbLoad
からは、EmployeeDAOImpl
のload
がコールされ、EmployeeModel
が戻されます。これは、m_emp
クラス変数の移入に使用されます。
getEmployeeDetails
は、手順1から戻されたEmployee
Beanを使用してgetDetails
をコールします。
getDetails
から、EmployeeModel
がJSPに戻されます。EmployeeBean
クラスによって、ejbFindByPrimaryKey(int empId)
メソッドを実装します。このメソッドによって、EmployeeDAOImpl
クラスをコールして、データベースからデータを取得します。
// from EmployeeBean.java public Integer ejbFindByPrimaryKey(int empId) throws FinderException { try { if (m_dao == null) m_dao = new EmployeeDAOImpl(); Integer findReturn = m_dao.findByPrimaryKey(empId); return findReturn; } catch (Exception e) { throw new FinderException ("¥nSQL Exception in find by primary key.¥n" + e.getMessage()); } }
EmployeeDAOImpl
クラスでは、findByPrimaryKey(int id)
メソッドによって、指定された従業員IDについて、データベースへの問合せを実行します。データベースに対してSELECT
文が実行され、指定された従業員が見つかった場合、その従業員IDが戻されます。指定された従業員が見つからなかった場合は、例外がスローされます。
給付データについては、1人のユーザーに2つ以上の給付項目が対応している場合もあります。その場合、アプリケーションではコレクションを繰り返し処理します。
// from queryEmployee.jsp <h4>Elected Benefits</h4> <table> <% Collection benefits = emp.getBenefits(); if (benefits == null || benefits.size() == 0) { %> <tr><td>None</td></tr> <% } else { Iterator it = benefits.iterator(); while (it.hasNext()) { BenefitItem item = (BenefitItem)it.next(); %> <tr><td><%=item.getName()%></td></tr> <% } // end of while } // end of if %> </table>図6-3 従業員の問合せのシーケンス図
追加処理および削除処理の場合には、JSPを使用して、追加または削除する給付項目、および従業員IDをEmployeeManager
に送信します。EmployeeManager
によって、給付項目が追加または削除され、その処理のステータスが戻されます。
給付項目の追加処理および削除処理は、給付項目のリストをユーザーに表示して、データベース上で追加処理または削除処理を実行するのと同様の流れになります。
<a href="/empbft/controller?empID=<%=id%>&action=addBenefitToEmployee"> Add benefits to the employee</a>
<a href="/empbft/controller?empID=<%=id%>&action=removeBenefitFromEmployee"> Remove benefits from the employee</a>
追加処理および削除処理の詳細は、以降の項を参照してください。
この項では、給付項目の追加処理について説明します。
図6-4は、ユーザーが給付項目の追加オプションを選択した場合に発生するイベントのフローを図で示したものです。
action
パラメータの値(addBenefitToEmployee
)を取得して、対応するクラスであるAddBenefitToEmployee
のperformAction
メソッドを起動します。
performAction
メソッドは、benefits
パラメータの値をチェックします。この値は、最初はNULLです。そのため、リクエストはaddBenefitToEmployee.jsp
(またはaddBenefitToEmployeeWireless.jsp
)に転送されます。JSPによって、ユーザーが追加可能な給付項目のリストが表示されます。action
パラメータは、まだ同じ値(addBenefitToEmployee
)です。しかし、このとき、追加する給付項目を指定するbenefits
パラメータも含まれます。
AddBenefitToEmployee
クラスを起動して、リクエストを処理します。このクラスでは、benefits
パラメータがNULLでないことを確認します。そして、Employee
クラスのaddBenefits
メソッドをコールして、給付項目を追加します。ユーザーが追加可能な給付項目のリストを表示するには、addBenefitToEmployee.jsp
ページを使用して、そのユーザーが選択していない給付項目のリストを取得します。JSPファイルによって、EmployeeManager
のインスタンスを取得した後、getUnelectedBenefitItems
メソッドを起動します。
// from addBenefitToEmployee.jsp <% int empId = Integer.parseInt(request.getParameter( SessionHelper.EMP_ID_PARAMETER)); EmployeeManager mgr = SessionHelper.getEmployeeManager(request); Collection unelected = mgr.getUnelectedBenefitItems(empId); ... %>
getUnelectedBenefitItems
メソッドは、BenefitCatalog
から、すべての給付項目が含まれるマスター・リストを取得します。その後、その従業員用の給付項目リストを取得します。そして、それら2つのリストを比較して、その従業員が選択していない給付項目のリストを戻します。
// from EmployeeManagerBean.java public Collection getUnelectedBenefitItems(int id) throws RemoteException { Collection allBenefits = null; InitialContext initial = new InitialContext(); Object objref = initial.lookup(AppJNDINames.BENEFIT_CATALOG_EJBHOME); BenefitCatalogHome home = (BenefitCatalogHome) PortableRemoteObject.narrow(objref, BenefitCatalogHome.class); BenefitCatalog catalog = home.create(); allBenefits = catalog.getBenefits(); // ... exceptions omitted ... Collection unelected = new ArrayList(); EmployeeModel emp = this.getEmployeeDetails(id); ArrayList eb = (ArrayList) emp.getBenefits(); if (eb != null && !eb.isEmpty()) { Iterator i = allBenefits.iterator(); while (i.hasNext()) { BenefitModel b = (BenefitModel)i.next(); if (Collections.binarySearch(eb, b) < 0) unelected.add(b); } return unelected; } return allBenefits; }
ユーザーが選択した給付項目を追加するには、AddBenefitToEmployee
オブジェクトによって、Employee
オブジェクトを取得し、addBenefits
メソッドを実行します。
// from AddBenefitToEmployee.java String benefits[] = req.getParameterValues(SessionHelper.BENEFIT_PARAMETER); ... int benefitIDs[] = new int[benefits.length]; for (int i = 0; i < benefits.length; i++) { benefitIDs[i] = Integer.parseInt(benefits[i]); } int empId = Integer.parseInt(req.getParameter(SessionHelper.EMP_ID_PARAMETER)); EmployeeManager mgr = SessionHelper.getEmployeeManager(req); try { Employee emp = mgr.getEmployee(empId); emp.addBenefits(benefitIDs); } catch (RemoteException e) { throw new ServletException ( "¥nRemote exception while getting employee and adding benefits.¥n" + e.getMessage()); } forward(req, res, wireless ? "/successWireless.jsp" : "/success.jsp");
Employee
オブジェクトのaddBenefits
メソッドは、EmployeeDAOImpl
クラスを使用してデータベースに接続します。
// from EmployeeBean.java public void addBenefits(int benefits[]) { try{ if (m_dao == null) m_dao = new EmployeeDAOImpl(); m_dao.addBenefits(m_emp.getId(), benefits); ejbLoad(); } catch (Exception e) { throw new EJBException ("¥nData access exception in adding benefits.¥n" + e.getMessage()); } }
addBenefits
メソッドは、データベースに給付項目を追加した後、ejbLoad
メソッドをコールして、Employee
Beanとデータベース内のデータを同期化します。
EmployeeDAOImpl
のaddBenefits
メソッドはデータベースに接続し、INSERT
文を送信します。
この項では、給付項目の削除処理について説明します。
図6-6は、ユーザーが削除する給付項目を選択して「Submit」ボタンをクリックした場合に発生するイベントのフローを図で示したものです。
action
パラメータの値(removeBenefitFromEmployee
)を取得して、対応するクラスであるRemoveBenefitFromEmployee
のperformAction
メソッドを起動します。
performAction
メソッドは、benefits
パラメータの値をチェックします。この値は、最初はNULLです。そのため、リクエストはremoveBenefitFromEmployee.jsp
(またはremoveBenefitFromEmployeeWireless.jsp
)に転送されます。JSPによって、ユーザーが削除可能な給付項目のリストが表示されます。action
パラメータは、まだ同じ値(removeBenefitFromEmployee
)です。しかし、このとき、削除する給付項目を指定するbenefits
パラメータも含まれます。
RemoveBenefitFromEmployee
クラスを起動して、リクエストを処理します。このクラスでは、benefits
パラメータがNULLでないことを確認します。そして、Employee
クラスのremoveBenefits
メソッドをコールして、給付項目を削除します。ユーザーが削除可能な給付項目のリストを表示するには、removeBenefitFromEmployee.jsp
によって、従業員のすべてのデータが含まれるEmployeeModel
を取得します。その後、EmployeeModel
のgetBenefits
メソッドをコールします。次に、リストを繰り返し処理して、各給付項目を表示します。
<% int empId = Integer.parseInt(request.getParameter( SessionHelper.EMP_ID_PARAMETER)); EmployeeManager mgr = SessionHelper.getEmployeeManager(request); Collection elected = mgr.getEmployeeDetails(empId).getBenefits(); if (elected == null || elected.size() == 0) { %> <h4>No Benefits to Remove</h4> <p>The employee has not elected any benefits.</p> <h4>Actions</h4> <a href="./controller?action=queryEmployee&empID=<%=empId%>">Query the same employee</a><br> <a href="./controller?action=queryEmployee">Query other employee</a><br> <a href="./">Home</a><br> <% } else { %> <h4>Select Elected Benefits</h4> <% Iterator i = elected.iterator(); while (i.hasNext()) { BenefitItem b = (BenefitItem) i.next(); %> <input type=checkbox name=benefits value=<%=b.getId()%>><%=b.getName()%><br> <% } // End of while %> <h4>Actions</h4> <input type=submit value="Remove Selected Benefits"> <input type=hidden name=empID value=<%=empId%>> <input type=hidden name=action value=<%=SessionHelper.ACTION_REMOVE_BENEFIT_FROM_EMPLOYEE%>> <% } // End of if %>
ユーザーが選択した給付項目を削除するには、RemoveBenefitFromEmployee
オブジェクトによって、Employee
オブジェクトを取得し、removeBenefits
メソッドを実行します。
// from RemoveBenefitFromEmployee.java String benefits[] = req.getParameterValues(SessionHelper.BENEFIT_PARAMETER); String client = req.getParameter(SessionHelper.CLIENT_TYPE_PARAMETER); boolean wireless = client != null && client.equals(SessionHelper.CLIENT_TYPE_WIRELESS); if(benefits == null) { forward(req, res, wireless ? "/removeBenefitFromEmployeeWireless.jsp" : "/removeBenefitFromEmployee.jsp"); } else { int benefitIDs[] = new int[benefits.length]; for (int i = 0; i < benefits.length; i++) { benefitIDs[i] = Integer.parseInt(benefits[i]); } int empId = Integer.parseInt(req.getParameter( SessionHelper.EMP_ID_PARAMETER)); EmployeeManager mgr = SessionHelper.getEmployeeManager(req); try { Employee emp = mgr.getEmployee(empId); emp.removeBenefits(benefitIDs); } catch (RemoteException e) { throw new ServletException ( "Remote exception while getting employee and removing his/her benefits." + e.getMessage()); } forward(req, res, wireless ? "/successWireless.jsp" : "/success.jsp"); }
Employee
オブジェクトのremoveBenefits
メソッドは、EmployeeDAOImpl
クラスを使用してデータベースに接続します。
// from EmployeeBean.java public void removeBenefits(int benefits[]) { try { if (m_dao == null) m_dao = new EmployeeDAOImpl(); m_dao.removeBenefits(m_emp.getId(), benefits); ejbLoad(); } catch (Exception e) { throw new EJBException ("¥nData access exception in removing benefits.¥n" + e.getMessage()); } }
removeBenefits
メソッドは、データベースから給付項目を削除した後、ejbLoad
メソッドをコールして、Employee
Beanとデータベース内のデータを同期化します。
EmployeeDAOImpl
のremoveBenefits
メソッドはデータベースに接続し、DELETE
文を送信します。
|
Copyright © 2003, 2004, Oracle. All Rights Reserved. |
|