|
Helping ordinary people create extraordinary websites! |
JSF for Nonbelievers: The JSF Application LifecycleBy Rick Hightower2005-05-05
Use Case 1: Add a New CD In the first use case for the application, the user adds a new CD by going to the CD listing page and clicking the Add CD link, which is defined in the listing.jsp file, as shown in Listing 1. Listing 1. Add CD button defined in listing.jsp <h:commandLink action="#{CDManagerBean.addNew}">
This link is bound to the CDManagerBean's addNew method. The addNew method is invoked in the (final) invoke application phase of the JSF lifecycle. The action is bound to this method with the JSF binding expression #{CDManagerBean.addNew}. CDManagerBean is an alias for the application's store controller. CDManagerBean is the logical name for the controller. The controller class is a managed bean defined in the faces-config.xml file, as shown in Listing 2.
Listing 2. StoreController class defined in faces-config.xml <managed-bean>Preparing the form The addNew() method prepares the form by creating an empty CD, as shown in Listing 3. Listing 3. addNew() creates an empty CD form [StoreController.java]The addNew() method blanks out the CD form fields by creating a new CD. The fields of the CD form are bound to the cd property's properties. This method also blanks out the list of subcategories being displayed. Returning a successful result Next, the addNew() method is invoked, and control is redirected to the success mapping, which is the cdForm.jsp file. The cdForm.jsp file is defined in the faces-config.xml file, as shown in Listing 4. Listing 4. cdForm.jsp is the success mapping for addNew() <navigation-rule>Listing 4 states that if the user went from the listing to the addNew (#{CDManagerBean.addNew}) action, and the addNew action returned success, then would go to the cdForm.jsp. Setting up the cdForm and panelGrid cdForm.jsp is the form that contains the CD form. It has fields for ID, Title, Artist, Price, Category, and Subcategory. The fields are placed in a container called a panelGrid. JSF components, like AWT components, have containers and components. A container is a component that contains other components. This is an example of the composite design pattern. The panelGrid has three columns. Each field is laid out on its own row with a label and a message to display error messages for the field. The cdForm and panelGrid are defined in Listing 5. Listing 5. cdForm and panelGrid defined <f:view>Notes about the code Each input field binds the field to a property of the controller's cd property. For example, the input text field for the title is bound to the cd property with the following JSF binding expression: value="#{CDManagerBean.cd.title}". You likely noticed that there is hardly any HTML in Listing 5. This is because the panelGrid generates most of the HMTL. Note that the real look and feel is determined by the style sheets associated with the panelGrid. The attribute rowClasses="row1, row2" sets the CSS classes for alternating rows. Row1 is white, and Row2 is gray. You can also specify the CSS classes for columns and much more. The JSF panelGrid component makes it convenient to quickly lay out a form. If you want to do something that the panelGrid does not provide, you don't have to use it: You can lay out your components using HTML. However, if you find that you use custom HTML on many pages, you may want to consider writing your own custom component. The idea is to make your reusable HTML as DRY as possible (DRY stands for don't repeat yourself, a term coined by Dave Thomas, the Pragmatic Programmer). Something else to note about Listing 5 is that the controller presents an editMode property, which is used by the cdForm.jsp to selectively display the submitAdd button or thesubmitUpdate button; the submitAdd button is displayed when the form is not in edit mode. The submitUpdate button is displayed when the form is in edit mode. This makes it easy to use the same JSP for edit and add mode. (By default, the form is not in edit mode.) This magic is accomplished by the rendered expression on each button in the cdForm.jsp. For example, Listing 6 shows the rendered expression on the submitAdd button rendered="#{not CDManagerBean.editMode}". The submitAdd button is bound to the addCD method using the expression (action="#{CDManagerBean.addCD}") . Listing 6. Adding a CD using the addCD() method [StoreController.java]Validating the fields Before the addCD method is invoked, JSF has to validate the fields from the GUI. This is actually fairly easy, since you haven't associated the fields with any validators. The values are copied from the request parameters to the components' values (by the components themselves) in the apply request value phase. At this point, the price is converted from a string to a float. If the user entered "abc" for the price, the conversion to float would fail, and control would be redirect to the cdForm.jsp page for the end user to fix. The h:message associated with the price would display a conversion error message. If all the values could be converted and were present (if required to be present), you could advance to validation processing. Since this example application doesn't have validators associated with the components (I'll introduce this feature in the next article), you'll simply advance to the update model values phase. In the update model values phase, the setter methods on the CD are invoked with the converted and validated values stored in the GUI components. The addCD() method is invoked in the invoke application phase. The addCD() method uses a business delegate (a store object) to perform this operation. The addCD method uses the store object to store the CD in the system. Since the addCD method returns success, the listing will be displayed next, as defined in faces-config.xm. The navigation rule defined in faces-config.xml is shown in Listing 7. Listing 7. Navigation rule for the addCD successful outcome <navigation-rule> Tutorial Pages: » Walk Through the 6 Phases of JSF's Request Processing Lifecycle » The JSF Lifecycle: an Overview » Phase 1: Restore View » Phase 2: Apply Request Values » Phase 3: Process Validation » Phase 4: Update Model Values » Phase 5: Invoke application » Phase 6: Render Response » A Working Example » Let's Code it » Use Case 1: Add a New CD » Use Case 2: Edit a CD » Use Case 3: Sort CDs » Immediate Event Handling » Conclusion » Resources First published by IBM DeveloperWorks |
|