JSF Life Cycle, Conversion, Validation, and Phase Listeners Skill Level: Introductory
Total Page:16
File Type:pdf, Size:1020Kb
Getting started with JavaServer Faces 1.2, Part 2: JSF life cycle, conversion, validation, and phase listeners Skill Level: Introductory Richard Hightower ([email protected]) CTO ArcMind 29 Jan 2008 This tutorial series covers how to get started with Java™ Server Faces (JSF) technology, a server-side framework that offers a component-based approach to Web user-interface development. Part 1 gets you started with a JSF 1.2 overview and a basic application. This sequel gives you a firm grasp of JSF's more-advanced features: custom validators, converters, and phase listeners. Along the way you'll gain an understanding of the JSF application life cycle. Section 1. Before you start About this series Get an introduction to Java™ Server Faces (JSF) technology, a server-side user-interface component framework for Java-based Web applications. This series is for developers who are new to JSF and want to come up to speed quickly — not just with JSF, but with using JSF components to reduce effort. This series covers just the essentials, with lots of examples. JSF is a more-traditional GUI development environment like AWT, SWT, and Swing. One of its major benefits is that it makes Web development easier by putting the hard work on the framework developers, not the application developers. Granted, JSF itself is more complex than many other Web frameworks, but the complexity is JSF life cycle, conversion, validation, and phase listeners © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 1 of 52 developerWorks® ibm.com/developerWorks hidden from the application developer. It is much easier to develop Web applications in JSF than in most other frameworks: it requires less code, less complexity, and less configuration. If you are doing Java server-side Web development, JSF is the easiest framework to learn. It is geared for creating Web applications (not Web sites). It allows you to focus on your Java code without handling request objects, session objects, or request parameters, or dealing with complicated XML files. With JSF, you can get more things done more quickly than with other Java Web frameworks. About this tutorial This tutorial picks up where Part 1 leaves off. If you are new to JSF or just want a refresher, then read the first installment before you begin this one. Even if you are an old JSF pro, there is likely a gem or two in that will help you out. Although tool support is a main benefit of JSF, you won't use fancy tools or IDE support in this tutorial. This tutorial covers the essentials with just background information to keep the discussion going and to keep you productively learning to use JSF to build Web applications. Objectives In this tutorial, continue getting an overview of JSF's features, and learn how to work with all of the JSF components. Build a simple contact-management application — a basic CRUD (create, read, update, delete) listing. After learning about the JSF application life cycle, improve the application with custom converters and validators. The tutorial winds down with a taste of some advanced JSF programming: create an object-level validation framework using a phase listener. Who should take this tutorial? If you are new to JSF, this tutorial is for you. Even if you have used JSF but have not tried out the JSF 1.2 features or have only used GUI tools to build JSF applications, you will likely learn a lot from both tutorials in this series. Prerequisites This tutorial is written for Java developers whose experience is at a beginning to intermediate level. You should have a general familiarity with using the Java language, with some GUI development experience. JSF life cycle, conversion, validation, and phase listeners Page 2 of 52 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks® System requirements To run the examples in this tutorial, you need a Java development environment (JDK) and Apache Maven. It helps to also have a Java IDE. Maven project files and Eclipse Java EE and Web Tools Project (WTP) project files are provided. See Download to obtain the example code. Visit the author's companion site (see Resources) for additional information about how to run the examples. Section 2. Sample JSF CRUD application This section introduces a simple CRUD application that you'll build on in subsequent sections to learn about: • Each of JSF's standard HTML components • Creating custom converters • Working with validators • Working with phase listeners A contact-management application The application you'll build in this section is a contact-management application that's similar in structure to the calculator application in Part 1. As you can see in Figure 1, the application is a standard CRUD listing. It requires no navigation rules because the whole application uses a single view (the contacts.jsp page). Figure 1. Contact-management sample application JSF life cycle, conversion, validation, and phase listeners © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 3 of 52 developerWorks® ibm.com/developerWorks Figure 2 shows the basic flow through the application: Figure 2. Contact-management sample application, link chase JSF life cycle, conversion, validation, and phase listeners Page 4 of 52 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks® This CRUD application consists of the following elements: • ContactController: The JSF controller • Contact: The model object that represents contact information • ContactRepository: The model object that creates, reads, updates, and deletes Contact objects • contacts.jsp: The JavaServer Pages (JSP) page that lays out the JSF component tree for managing contacts • faces-config.xml: The JSF configuration, where you declare ContactController and ContactRepository as managed beans, and inject ContactRepository into ContactController ContactController ContactController backs the contacts.jsp page. Listing 1 shows the code for ContactController: Listing 1. ContactController package com.arcmind.contact.controller; import java.util.List; import javax.faces.application.FacesMessage; import javax.faces.component.UICommand; import javax.faces.component.UIForm; import javax.faces.context.FacesContext; import com.arcmind.contact.model.Contact; import com.arcmind.contact.model.ContactRepository; public class ContactController { /** Contact Controller collaborates with contactRepository. */ private ContactRepository contactRepository; /** The current contact that is being edited. */ private Contact contact = new Contact(); /** Contact to remove. */ private Contact selectedContact; /** The current form. */ private UIForm form; /** Add new link. */ private UICommand addNewCommand; /** Persist command. */ private UICommand persistCommand; /** For injection of collaborator. */ public void setContactRepository(ContactRepository contactRepository) { this.contactRepository = contactRepository; JSF life cycle, conversion, validation, and phase listeners © Copyright IBM Corporation 1994, 2008. All rights reserved. Page 5 of 52 developerWorks® ibm.com/developerWorks } public void addNew() { form.setRendered(true); addNewCommand.setRendered(false); persistCommand.setValue("Add"); } public void persist() { form.setRendered(false); addNewCommand.setRendered(true); if (contactRepository.persist(contact) == null) { addStatusMessage("Added " + contact); } else { addStatusMessage("Updated " + contact); } } public void remove() { contactRepository.remove(selectedContact); addStatusMessage("Removed " + selectedContact); } public void read() { contact = selectedContact; form.setRendered(true); addNewCommand.setRendered(false); addStatusMessage("Read " + contact); persistCommand.setValue("Update"); } private void addStatusMessage(String message) { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_INFO, message, null)); } //most getter/setter omitted } Listing 1 creates a CRUD GUI in fewer than 74 lines of code — not too bad. ContactController is managed in request scope, so a new Contact is created when a ContactController is instantiated. Three components — form (of type UIForm), addNewCommand (of type UICommand), and persistCommand (of type UICommand) — are bound to the ContactController. The addNew() method ensures that: • form is turned on so the user can enter a new contact — form.setRendered(true) • addNewCommand is turned off — addNewCommand.setRendered(false) • persistCommand's label is set to Add — persistCommand.setValue("Add") The persist() method handles both updating an existing contact and adding a new contact using the contactRepository. The persist() method turns the JSF life cycle, conversion, validation, and phase listeners Page 6 of 52 © Copyright IBM Corporation 1994, 2008. All rights reserved. ibm.com/developerWorks developerWorks® form off and the addNewCommand on. The remove() method removes the contact from the system using the contactRepository. The read() method copies the selectedContact (of type Contact) to the contact. (The contact — also of type Contact — is value bound to the form.) You might wonder where the selectedContact comes from. It is selected when the user clicks a contact in the contact listing. (This tutorial covers it when discussing the JSP.) As in Part 1, addStatusMessage adds status messages so you can display them with <h:messages>. Contacts view The JSP page uses a <h:dataTable> (a component not covered in Part 1), as shown in Listing 2: Listing 2. contacts.jsp <?xml version="1.0" encoding="ISO-8859-1"