📄 ebank4.html
字号:
Design Strategies</h3><a name="wp80098"> </a><p class="pBody">The main job of the JSP pages in the Duke's Bank application is presentation. In order to achieve this, most dynamic processing tasks are delegated to enterprise beans, custom tags, and JavaBeans components. </p><a name="wp83391"> </a><p class="pBody">In the Duke's Bank application, the JSP pages use enterprise beans to handle interactions with the database. In addition, the JSP pages rely on JavaBeans components for interactions with the enterprise beans. In the Duke's Bookstore application, presented in chapters <a href="Servlets.html#wp69954">11</a> to <a href="JSPTags.html#wp74641">15</a>, the <code class="cCode">BookDB</code> JavaBeans component acted as a front end to a database or as a facade to the interface provided by an enterprise bean. In the Duke's Bank application, <code class="cCode"><a href="../bank/src/com/sun/ebank/web/TransferBean.java" target="_blank">TransferBean</a></code> plays the same role. However, the other JavaBeans components have much richer functionality. <code class="cCode"><a href="../bank/src/com/sun/ebank/web/ATMBean.java" target="_blank">ATMBean</a></code> invokes enterprise bean methods and sets acknowledgement strings according to customer input, and <code class="cCode"><a href="../bank/src/com/sun/ebank/web/AccountHistoryBean.java" target="_blank">AccountHistoryBean</a></code> massages the data returned from the enterprise beans in order to present the view of the data required by the customer.</p><a name="wp83403"> </a><p class="pBody">The Web client uses a template mechanism implemented by custom tags (discussed in <a href="JSPTags7.html#wp90689">A Template Tag Library</a>) to maintain a common look across all the JSP pages. The template mechanism consists of three components:</p><div class="pSmartList1"><ul class="pSmartList1"><a name="wp80122"> </a><div class="pSmartList1"><li><code class="cCode"><a href="../bank/web/template/template.txt" target="_blank">template.jsp</a></code> determines the structure of each screen. It uses the <code class="cCode">insert</code> tag to compose a screen from subcomponents.</li></div><a name="wp80124"> </a><div class="pSmartList1"><li><code class="cCode"><a href="../bank/web/template/screendefinitions.txt" target="_blank">screendefinitions.jspf</a></code> defines the subcomponents used by each screen. All screens have the same banner, but different title and body content (specified by the JSP Pages column in <a href="Ebank4.html#wp83281">Table 32-7</a>).</li></div><a name="wp80129"> </a><div class="pSmartList1"><li><code class="cCode"><a href="../bank/src/com/sun/ebank/web/Dispatcher.java" target="_blank">Dispatcher</a></code>, a servlet, processes requests and forwards to <code class="cCode">template.jsp</code>.</li></div></ul></div><a name="wp80131"> </a><p class="pBody">Finally, the Web client uses logic tags from the JSTL <code class="cCode">core</code> tag library to perform flow control and the JSTL <code class="cCode">fmt</code> tag library to localize messages and format currency.</p><a name="wp80135"> </a><h3 class="pHeading2">Web Client Life Cycle</h3><a name="wp80136"> </a><h4 class="pHeading3">Initializing the Client Components</h4><a name="wp80137"> </a><p class="pBody">Responsibility for managing the enterprise beans used by the Web client rests with the <code class="cCode"><a href="../bank/src/com/sun/ebank/web/BeanManager.java" target="_blank">BeanManager</a></code> class. It creates customer, account, and transaction controller enterprise beans and provides methods for retrieving the beans. </p><a name="wp80139"> </a><p class="pBody">When instantiated, <code class="cCode">BeanManager</code> retrieves the home interface for each bean from the helper class <code class="cCode"><a href="../bank/src/com/sun/ebank/util/EJBGetter.java" target="_blank">EJBGetter</a></code> and creates an instance by calling the <code class="cCode">create</code> method of the home interface. This is a session-level function: <code class="cCode">BeanManager</code> is created and stored as a session attribute.</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public class BeanManager { private CustomerController custctl; private AccountController acctctl; private TxController txctl; public BeanManager() { if (custctl == null) { try { CustomerControllerHome home = EJBGetter.getCustomerControllerHome(); custctl = home.create(); } catch (RemoteException ex) { Debug.print("Couldn't create customer bean." + ex.getMessage()); } catch (CreateException ex) { Debug.print("Couldn't create customer bean." + ex.getMessage()); } catch (NamingException ex) { Debug.print("Unable to lookup home: " + CodedNames.CUSTOMER_CONTROLLER_EJBHOME + ex.getMessage()); } } public CustomerController getCustomerController() { return custctl; } ...}<a name="wp82667"> </a></pre></div><a name="wp81265"> </a><h4 class="pHeading3">Request Processing</h4><a name="wp80153"> </a><p class="pBody">All requests for the URLs listed in <a href="Ebank4.html#wp83281">Table 32-7</a> are mapped to the <code class="cCode">dispatcher</code> Web component, which is implemented by the <code class="cCode">Dispatcher</code> servlet: </p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">public class Dispatcher extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) { ... String selectedScreen = request.getServletPath(); ... if (selectedScreen.equals("/accountHist")) { ... } else if (selectedScreen.equals("/transferAck")) { String fromAccountId = request.getParameter("fromAccountId"); String toAccountId = request.getParameter("toAccountId"); if ( (fromAccountId == null) || (toAccountId == null)) { request.setAttribute("errorMessage", messages.getString("AccountError")); try { request.getRequestDispatcher( "/error.jsp").forward(request, response); } catch(Exception ex) { } } else { TransferBean transferBean = new TransferBean(); request.setAttribute("transferBean", transferBean); try { transferBean.setMessages(messages); transferBean.setFromAccountId(fromAccountId); transferBean.setToAccountId(toAccountId); transferBean.setBeanManager(beanManager); transferBean.setTransferAmount(new BigDecimal(request. getParameter("transferAmount"))); String errorMessage = transferBean.doTx(); if (errorMessage != null) { request.setAttribute("errorMessage", errorMessage); try { request.getRequestDispatcher( "/error.jsp").forward(request, response); } catch(Exception ex) { } } } catch (NumberFormatException e) { request.setAttribute("errorMessage", messages.getString("AmountError")); try { request.getRequestDispatcher( "/error.jsp").forward(request, response); } catch(Exception ex) { } } } ... try { request.getRequestDispatcher( "/template/template.jsp").forward(request, response); } catch(Exception e) { } }}<a name="wp82783"> </a></pre></div><a name="wp80156"> </a><p class="pBody">When a request is delivered, <code class="cCode">Dispatcher</code> does the following:</p><div class="pSmartList1"><ol type="1" class="pSmartList1"><a name="wp80157"> </a><div class="pSmartList1"><li>Retrieves and saves the incoming request URL in the request attribute <code class="cCode">selectedScreen</code>. This is done because the URL will be modified when the request is later forwarded to the application's template page. </li></div><a name="wp80158"> </a><div class="pSmartList1"><li>Creates a JavaBeans component and stores the bean as a request attribute.</li></div><a name="wp80159"> </a><div class="pSmartList1"><li>Parses and validates the request parameters. If a parameter is invalid, <code class="cCode">Dispatcher</code> may reset the request alias to an error page. Otherwise, it initializes the JavaBeans component.</li></div><a name="wp80160"> </a><div class="pSmartList1"><li>Calls the <code class="cCode">doTx</code> method of the JavaBeans component. This method retrieves data from the enterprise beans and processes the data according to options specified by the customer.</li></div><a name="wp80161"> </a><div class="pSmartList1"><li>Forwards the request to <code class="cCode">template.jsp</code>.</li></div></ol></div><a name="wp80162"> </a><p class="pBody">As mentioned earlier, <code class="cCode">template.jsp</code> generates the response by including the responses from subcomponents. If the request is a <code class="cCode">GET</code>, the body subcomponent usually retrieves data from the enterprise bean directly; otherwise it retrieves data from the JavaBeans component initialized by <code class="cCode">Dispatcher</code>.</p><a name="wp80167"> </a><p class="pBody"><a href="Ebank4.html#wp80173">Figure 32-9</a> depicts the interaction between these components.</p><a name="wp80171"> </a><p class="pBody"></p><div align="left"><img src="images/Fig447.gif" height="399" width="436" alt="Web Component Interaction" border="0" hspace="0" vspace="0"/></div><p class="pBody"></p><p> <a name="80173"> </a><strong><font >Figure 32-9 Web Component Interaction</font></strong></p><a name="wp80174"> </a><h3 class="pHeading2">Protecting the Web Resources</h3><a name="wp80175"> </a><p class="pBody">In the J2EE platform, a Web resource is protected from anonymous access by specifying which security roles can access the resource. The Web container guarantees that only certain users acting in those roles can access the resource. In order for the Web container to enforce the security constraint, the application must specify a means for users to identify themselves and the Web container must support mapping a role to a user.</p><a name="wp80186"> </a><p class="pBody">In the Duke's Bank Web client, you restrict all of the URLs listed in <a href="Ebank4.html#wp83281">Table 32-7</a> to the security role <code class="cCode">bankCustomer</code>. The application requires users to identify themselves via the form-based login mechanism. When a customer tries to access a Web client URL, and has not been authenticated, the Web container displays the JSP page <code class="cCode"><a href="../bank/web/logon.txt" target="_blank">logon.jsp</a></code>. This page contains a form that requires a customer to enter an identifier and password.</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative"><form action="j_security_check" method=post><table><tr> <td align="center" > <table border="0"> <tr> <td><b><fmt:message key="CustomerId"/></b></td> <td> <input type="text" size="15" name="j_username"> </td> </tr> <tr> <td><b><fmt:message key="Password"/></b></td> <td> <input type="password" size="15" name="j_password"> </td> ...</form><a name="wp80189"> </a></pre></div><a name="wp80190"> </a><p class="pBody">Note that the action invoked by the form, <code class="cCode">j_security_check</code>, is specified by the Java Servlet specification, as are the request parameters <code class="cCode">j_username</code> and <code class="cCode">j_password</code>. The Web container retrieves this information, maps it to a security role, and verifies that the role matches that specified in the security constraint. Note that in order for the Web container to check the validity of the authentication information and perform the mapping, you must perform these two steps when you deploy the application:</p><div class="pSmartList1"><ol type="1" class="pSmartList1"><a name="wp80191"> </a><div class="pSmartList1"><li>Add the customer's group, ID, and password to the default realm of the container using the Admin Console.</li></div><a name="wp80195"> </a><div class="pSmartList1"><li>Map the <code class="cCode">bankCustomer</code> role to the customer <em class="cEmphasis">or</em> customer's group in <code class="cCode">deploytool</code>.</li></div></ol></div><a name="wp80199"> </a><p class="pBody">Once the customer has been authenticated, the identifier provided by the customer is used as a key to identify the customer's accounts. The identifier is retrieved from the request using the following expression:</p><div class="pPreformattedRelative"><pre class="pPreformattedRelative">${pageContext.request.userPrincipal.name}<a name="wp82545"> </a></pre></div> </blockquote> <img src="images/blueline.gif" width="550" height="8" ALIGN="BOTTOM" NATURALSIZEFLAG="3" ALT="Divider"> <table width="550" summary="layout" id="SummaryNotReq1"> <tr> <td align="left" valign="center"> <font size="-1"> <a href="http://java.sun.com/j2ee/1.4/download.html#tutorial" target="_blank">Download</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/faq.html" target="_blank">FAQ</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/history.html" target="_blank">History</a> </td> <td align="center" valign="center"><a accesskey="p" href="Ebank3.html"><img id="LongDescNotReq1" src="images/PrevArrow.gif" width="26" height="26" border="0" alt="Prev" /></a><a accesskey="c" href="J2EETutorialFront.html"><img id="LongDescNotReq1" src="images/UpArrow.gif" width="26" height="26" border="0" alt="Home" /></a><a accesskey="n" href="Ebank5.html"><img id="LongDescNotReq3" src="images/NextArrow.gif" width="26" height="26" border="0" alt="Next" /></a><a accesskey="i" href="J2EETutorialIX.html"></a> </td> <td align="right" valign="center"> <font size="-1"> <a href="http://java.sun.com/j2ee/1.4/docs/api/index.html" target="_blank">API</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/search.html" target="_blank">Search</a> <br> <a href="http://java.sun.com/j2ee/1.4/docs/tutorial/information/sendusmail.html" target="_blank">Feedback</a></font> </font> </td> </tr> </table> <img src="images/blueline.gif" width="550" height="8" ALIGN="BOTTOM" NATURALSIZEFLAG="3" ALT="Divider"><p><font size="-1">All of the material in <em>The J2EE(TM) 1.4 Tutorial</em> is <a href="J2EETutorialFront2.html">copyright</a>-protected and may not be published in other workswithout express written permission from Sun Microsystems.</font> </body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -