|
Home TOC Index |
|
Search
Feedback |
Web Client
In the Duke's Bank application, the Web client is used by customers to access account information and perform operations on accounts. For example, Figure 18-6 shows an account history screen.
Table 18-2 lists the functions the client supports, the URLs used to access the functions, and the components that implement the functions.
Design Strategies
The main job of the JSP pages in the Duke's Bank application is presentation. A strategy for developing maintainable JSP pages is to minimize the amount of scripting embedded in the pages. In order to achieve this, most dynamic processing tasks are delegated to enterprise beans, custom tags, and JavaBeans components.
In the Duke's Bank application, the JSP pages use enterprise beans to handle interactions with the database. In addition, the JSP pages rely heavily on JavaBeans components for interactions with the enterprise beans. In the Duke's Bookstore application, presented in chapters 10 to 13, the
BookDBJavaBeans 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,TransferBeanplays the same role. However, the other JavaBeans components have much richer functionality.ATMBeaninvokes enterprise bean methods and sets acknowledgement strings according to customer input, andAccountHistoryBeanmassages the data returned from the enterprise beans in order to present the view of the data required by the customer.The Web client uses a template mechanism implemented by custom tags (discussed in A Template Tag Library) to maintain a common look across all the JSP pages. The template mechanism consists of three components:
template.jspdetermines the structure of each screen. It uses theinserttag to compose a screen from subcomponents.screendefinitions.jspdefines 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 Table 18-2).Dispatcher, a servlet, processes requests and forwards totemplate.jsp.Finally, the Web client uses three logic tags--
iterate,equal, andnotEqual--from the Struts tag library discussed in the section The Example JSP Pages to perform flow control.Web Client Life Cycle
Initializing the Client Components
Responsibility for managing the enterprise beans used by the Web client rests with the
BeanManagerclass. It creates customer, account, and transaction controller enterprise beans and provides methods for retrieving the beans.When instantiated,
BeanManagerretrieves the home interface for each bean from the helper classEJBGetterand creates an instance by calling thecreatemethod of the home interface. Because this is an application-level function,BeanManageritself is created and stored as a context attribute by aContextListener(see Handling Servlet Life-Cycle Events) when the client is first initialized.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) { System.out.println("..."); } catch (CreateException ex) { System.out.println(); } catch (NamingException ex) { System.out.println(); } } public CustomerController getCustomerController() { return custctl; } ... } public final class ContextListener implements ServletContextListener { private ServletContext context = null; ... public void contextInitialized(ServletContextEvent event) { this.context = event.getServletContext(); context.setAttribute("beanManager", new BeanManager()); context.log("contextInitialized()"); } ... }Request Processing
All requests for the URLs listed in Table 18-2 are mapped to the
dispatcherWeb component, which is implemented by theDispatcherservlet:public class Dispatcher extends HttpServlet { public void doPost(HttpServletRequest request, HttpServletResponse response) { ... String selectedScreen = request.getServletPath(); request.setAttribute("selectedScreen", selectedScreen); BeanManager beanManager = getServletContext().getAttribute( "beanManager"); ... 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("selectedScreen", "/error"); request.setAttribute("errorMessage", messages.getString("AccountError")); } else { TransferBean transferBean = new TransferBean(); request.setAttribute("transferBean", transferBean); transferBean.setMessages(messages); transferBean.setFromAccountId(fromAccountId); transferBean.setToAccountId(toAccountId); transferBean.setBeanManager(beanManager); try { transferBean.setTransferAmount(new BigDecimal(request. getParameter("transferAmount"))); String errorMessage = transferBean.populate(); if (errorMessage != null) { request.setAttribute("selectedScreen", "/error"); request.setAttribute("errorMessage", errorMessage); } } catch (NumberFormatException e) { request.setAttribute("selectedScreen", "/error"); request.setAttribute("errorMessage", messages.getString("AmountError")); } } ... try { request.getRequestDispatcher("/template.jsp"). forward(request, response); } catch(Exception e) { } } }When a request is delivered,
Dispatcherdoes the following:
- Retrieves and saves the incoming request URL in the request attribute
selectedScreen. This is done because the URL will be modified when the request is later forwarded to the application's template page.- Creates a JavaBeans component and stores the bean as a request attribute.
- Parses and validates the request parameters. If a parameter is invalid,
Dispatchermay reset the request alias to an error page. Otherwise, it initializes the JavaBeans component.- Calls the
populatemethod of the JavaBeans component. This method retrieves data from the enterprise beans and processes the data according to options specified by the customer.- Forwards the request to
template.jsp.As mentioned earlier,
template.jspgenerates the response by including the responses from subcomponents. If the request is aGET, the body subcomponent usually retrieves data from the enterprise bean directly; otherwise it retrieves data from the JavaBeans component initialized byDispatcher.Figure 18-7 summarizes the interaction between these components.
Figure 18-7 Web Component Interaction
Protecting the Web Resources
In the J2EE platform, a Web resource is protected from anonymous access by specifying which security roles can access the resource (see Controlling Access to Web Resources). This is known as a security constraint. The Web container guarantees that only certain users acting in roles specified in the security constraint 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 (described in Authenticating Users of Web Resources) and the Web container must support mapping a role to a user.
In the Duke's Bank Web client, all of the URLs listed in Table 18-2 are restricted to the security role
BankCustomer. 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 form-based login URL/logon, which is mapped to the JSP pagelogon.jsp. This page contains a form that requires a customer to enter an identifier and password. 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:
- Add the customer's group, ID, and password to the default realm of the container (see J2EE Users, Realms, and Groups).
- Map the
BankCustomerrole to the customer or customer's group (see J2EE Users, Realms, and Groups).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 as follows:
<% ArrayList accounts = beanManager.getAccountController().getAccountsOfCustomer( request.getUserPrincipal().getName()); %>
|
Home TOC Index |
|
Search
Feedback |