Docsity
Docsity

Prepare-se para as provas
Prepare-se para as provas

Estude fácil! Tem muito documento disponível na Docsity


Ganhe pontos para baixar
Ganhe pontos para baixar

Ganhe pontos ajudando outros esrudantes ou compre um plano Premium


Guias e Dicas
Guias e Dicas

JavaServer Faces JSF in Action, Manuais, Projetos, Pesquisas de Informática

Livro sobre java

Tipologia: Manuais, Projetos, Pesquisas

2014

Compartilhado em 04/04/2014

gustavo-dias-11
gustavo-dias-11 🇧🇷

4.7

(7)

46 documentos

1 / 1073

Documentos relacionados


Pré-visualização parcial do texto

Baixe JavaServer Faces JSF in Action e outras Manuais, Projetos, Pesquisas em PDF para Informática, somente na Docsity! Kito D. Mann Foreword by Ed Burns M A N N I N G JAVASERVER FACES IN ACTION To my beautiful wife and best friend, Tracey. This book would not exist without you, and I’m eternally grateful for the positive influence you’ve had on my life, always pushing me to be the best I can be.Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> PART 1 EXPLORING JAVASERVER FACES .................................. 1 1 ■ Introducing JavaServer Faces 3 2 ■ JSF fundamentals 38 3 ■ Warming up: getting around JSF 88 4 ■ Getting started with the standard components 137 5 ■ Using the input and data table components 185 6 ■ Internationalization, validators, and converters 234 PART 2 BUILDING USER INTERFACES ..................................... 275 7 ■ Introducing ProjectTrack 277 8 ■ Developing a user interface without Java code: the Login page 287 9 ■ Developing a user interface without Java code: the other pages 316 10 ■ Integrating application functionality 354 brief contentsvii Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> x CONTENTS 1.5 Hello, world! 22 Dissecting hello.jsp 24 ■ Dissecting goodbye.jsp 31 Examining the HelloBean class 32 ■ Configuration with faces-config.xml 34 ■ Configuration with web.xml 36 1.6 Summary 37 2 JSF fundamentals 382.1 The key pieces of the pie 39 User interface components 41 ■ Renderers 43 Validators 44 ■ Backing beans 45 ■ Converters 48 Events and listeners 49 ■ Messages 55 ■ Navigation 56 2.2 The Request Processing Lifecycle 57 Phase 1: Restore View 61 ■ Phase 2: Apply Request Values 63 Phase 3: Process Validations 65 ■ Phase 4: Update Model Values 66 ■ Phase 5: Invoke Application 66 ■ Phase 6: Render Response 68 2.3 Understanding component and client identifiers 69 Naming containers 72 ■ Referencing identifiers 73 2.4 Exploring the JSF expression language 76 Understanding scoped variables 80 ■ Using implicit variables 81 ■ Using the EL with components 83 2.5 Summary 86 3 Warming up: getting around JSF 883.1 Setting up your JSF environment 89 Basic requirements 89 ■ Choosing a JSF implementation 89 Directory structure 90 ■ Configuration 92 3.2 The role of JSP 102 Using JSP includes 103 ■ Using JSF with JSTL and other JSP custom tags 104 3.3 Creating and initializing beans 110 Declaring managed beans 113 ■ Declaring Lists and Maps as managed beans 123 ■ Setting values with value-binding expressions 125 3.4 Navigating the sea of pages 129 3.5 Summary 136Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> CONTENTS xi 4 Getting started with the standard components 1374.1 It’s all in the components 138 Using HTML attributes 142 ■ Understanding facets 143 The power of tools 145 ■ The render kit behind the scenes 148 4.2 Common component properties 148 4.3 Controlling the page with UIViewRoot 149 4.4 Setting component parameters with UIParameter 151 4.5 Displaying data with the Output components 153 Displaying ordinary text with HtmlOutputText 153 ■ Using UIOutput with the <f:verbatim> tag 155 ■ Creating input labels with HtmlOutputLabel 158 ■ Using HtmlOutputFormat for parameterized text 160 ■ Displaying hyperlinks with HtmlOutputLink 165 4.6 Displaying images with HtmlGraphicImage 167 4.7 Displaying component messages with HtmlMessage 169 4.8 Displaying application messages with HtmlMessages 172 4.9 Grouping and layout with the Panel components 176 Grouping components with HtmlPanelGroup 176 Creating tables with HtmlPanelGrid 178 4.10 Summary 184 5 Using the input and data table components 1855.1 Registering event listeners 186 Declaring value-change listeners 187 Declaring action listeners 187 5.2 Common component properties 189 5.3 Handling forms with HtmlForm 190 5.4 Handling basic user input 192 Declaring basic text fields with HtmlInputText 193 ■ Using HtmlInputTextarea for memo fields 194 ■ Displaying password fields with HtmlInputSecret 195 ■ Declaring hidden fields with HtmlInputHidden 197 Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> xii CONTENTS 5.5 Using HtmlSelectBooleanCheckbox for checkboxes 198 5.6 Defining item lists 199 Using UISelectItem for single items 200 ■ Using UISelectItems for multiple items 203 5.7 Handling multiple-item selections 205 Using HtmlSelectManyCheckbox for checkbox groups 205 Displaying listboxes with HtmlSelectManyListbox 208 Using HtmlSelectManyMenu for single-item listboxes 210 5.8 Handling single-item selections 212 Using HtmlSelectOneRadio for radio button groups 212 Using single-select listboxes with HtmlSelectOneListbox 215 Declaring combo boxes with HtmlSelectOneMenu 217 5.9 Executing application commands 219 Declaring buttons with HtmlCommandButton 219 Creating an action link with HtmlCommandLink 221 5.10 Displaying data sets with HtmlDataTable 223 5.11 Summary 233 6 Internationalization, validators, and converters 2346.1 Internationalization and localization 235 Looking into locales 236 ■ Creating resource bundles 238 Using resource bundles with components 241 Internationalizing text from back-end code 244 6.2 Input validation 245 Using validator methods 245 ■ Using validators 246 Using the standard validators 247 ■ Combining different validators 251 6.3 Type conversion and formatting 251 Using converters 254 ■ Working with the standard converters 255 6.4 Customizing application messages 269 6.5 Summary 273Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> CONTENTS xv PART 3 DEVELOPING APPLICATION LOGIC ........................ 407 11 The JSF environment 40911.1 From servlets to JSF 410 11.2 The application foundation 413 Application 413 ■ Evaluation expressions 417 11.3 It’s all in the context 419 FacesContext 420 ■ FacesMessage 422 ExternalContext 424 11.4 Event handling 428 FacesEvent 430 ■ Handling action events 432 ■ Handling value-change events 434 ■ Handling phase events 435 11.5 Components revisited 438 UIComponent 442 ■ UIViewRoot 446 ValueHolder 449 ■ EditableValueHolder 451 SelectItem and SelectItemGroup model beans 453 11.6 Summary 455 12 Building an application: design issues and foundation classes 456 12.1 Layers of the pie 457 12.2 Roasting the beans 460 The importance of toString 461 ■ Serialization for breakfast 462 ■ It’s all in the properties 462 Exposing beans 472 12.3 Exploring the business layer and data layers 473 12.4 Developing the application layer 476 Handling constants 478 ■ Organizing utility methods 480 Initializing singletons 482 ■ Adapting business objects 484 12.5 Writing a visit object for session state 491 12.6 Developing a base backing bean class 494 12.7 Summary 498Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> xvi CONTENTS 13 Building an application: backing beans, security, and internationalization 499 13.1 Writing backing beans 500 Thread safety 501 ■ Handling errors 501 ■ Performing authentication 505 ■ Listing projects with UIData and parameterizing listeners 511 ■ Updating projects 522 Creating new projects 528 ■ Paging through the project history with UIData 534 ■ Working with JDBC ResultSets and UIData 540 13.2 Adding security 545 Container-based vs. custom security 546 Using custom security 547 13.3 Supporting internationalization in code 551 Internationalizing text with resource bundles 552 Internationalizing messages 557 13.4 Design consequences and alternatives 562 Accessing the business layer 562 ■ Organizing beans by function 563 ■ Action methods implemented by backing beans 564 ■ Initializing backing bean properties with the Managed Bean Creation facility 565 13.5 Summary 566 14 Integrating JSF with Struts and existing applications 568 14.1 What integration means 569 14.2 When to use JSF with other frameworks 569 14.3 The many faces of requests and responses 571 14.4 Integrating JSF with Struts applications 572 First steps 575 ■ Migrating Struts JSP tags 577 Using JSF action methods and managed beans 597 Who’s controlling whom? 599 14.5 Integrating JSF with non-Struts applications 600 14.6 Summary 601Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> CONTENTS xvii PART 4 WRITING CUSTOM COMPONENTS, RENDERERS, VALIDATORS, AND CONVERTERS ................................ 603 15 The JSF environment: a component developer’s perspective 605 15.1 Three steps to UI extension nirvana 606 15.2 Developing UI components 607 Deciding when to write a UI component 608 ■ Classes and interfaces 610 ■ Event handling with method bindings 623 Registration 624 ■ JSP integration 627 15.3 Developing renderers 636 Deciding when to write a renderer 640 ■ Renderer 641 RenderKit 643 ■ Registration 644 ■ JSP integration 647 15.4 Developing validators 648 Validator 649 ■ Registration 650 ■ JSP integration 652 15.5 Developing converters 654 Converter 654 ■ Registration 657 ■ JSP integration 658 15.6 Handling internationalization 660 15.7 Packaging UI extensions 660 15.8 Summary 661 appendix A: Using JSF without JSP 665 references 675 index 679 online extension: See page xviii for contentsLicensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> xx ONLINE EXTENSION 19.3 Registering the component 810 19.4 Writing the ToolbarRenderer class 811 Encoding 811 ■ Decoding 820 19.5 Registering the renderer 821 19.6 JSP integration 822 Writing the Navigator_ToolbarTag component tag 822 Writing the NavigatorItemTag tag handler 826 Adding the tags to the tag library 831 19.7 Using the component 834 19.8 Summary 838 20 Validator and converter examples 83920.1 Validator methods vs. validator classes 840 20.2 Developing a validator 840 Writing the RegularExpressionValidator class 842 Registering the validator 847 ■ Integrating with JSP 847 Using the validator 852 20.3 When custom converters are necessary 854 20.4 Developing a converter 854 Writing the UserConverter class 856 ■ Registering the converter 865 ■ JSP integration 866 Using the converter 870 20.5 Summary 872 appendix B: A survey of JSF IDEs and implementations 873 appendix C: Extending the core JSF classes 935 appendix D: JSF configuration 958 appendix E: Time zone, country, language, and currency codes 976Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> foreword As I write this foreword, I am collaborating with four leading user interface (UI) component vendors on a presentation for the 2004 JavaOneSM conference. In our presentation, the vendors will show how they leverage JavaServerTM Faces technology in their products. While developing the presentation, I am learning some things about the work we’ve been doing on JavaServer Faces for the past three years. The vendors have their own set of concerns unique to adapting their product for JavaServer Faces, but they all voice one opinion loud and clear: they are very relieved to finally have a standard for web-based user interfaces. The absence of a standard for web-based UIs forced these component ven- dors to write special case code for every integrated development environment (IDE) into which they wanted to plug. Now that we have the JavaServer Faces standard, any IDE can declare compliance to that standard, and any vendor that also complies with the standard can plug components into the IDE with much less work. Of course, this means that any components you develop will also be able to plug into tools without too much additional work. The JavaServer Faces specification was developed by a community of lead- ing minds in the field of web UI development. We took the best ideas from many different approaches to UI frameworks and assembled them into one coherent whole. The trouble with standards is that they get rather complex in xxi order to solve the problems they are addressing. For JavaServer Faces, that Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> xxii FOREWORD problem is providing an easy-to-use UI framework built on top of a collection of technologies not well suited to UIs at all. This has led to a particularly complex specification to implement. Thankfully, the number of people actually implement- ing the spec is relatively small compared to those using those implementations, but as it turns out, knowing the specification in detail is still helpful in order to use it. As a member of the expert group developing the next version of JavaServer Pages, Kito is no stranger to technology standards. Kito grasps the key value-adds of JavaServer Faces and has explained them in a book that is accessible and in- depth. You will see what sets JavaServer Faces apart from other web UI frame- works, including its first-class component model, its well-defined state manage- ment system, and its conceptual similarity to JavaBeans. Kito is familiar with the abstractions being used by the specification, and, more important, he understands why we used those abstractions. Understanding the why of the specification leads to a superior explanation for you, the reader. For example, look at the “relation- ship of concepts” diagram in chapter 2. This is a great way to understand the ratio- nale for the design of JavaServer Faces. Kito also understands the marketplace into which this technology fits. This means you get the most important information first, so you can get your job done quickly and completely. He spends just enough time building a firm foundation of the technology underlying JavaServer Faces, making the book ideal for getting started from scratch. Finally, the book has all the things you’ve come to expect from a top-quality software technology book: a descriptive table of contents that can serve as a frame- work for understanding, chapter goals and summaries to save you time, and lots of working examples that you can use in your own projects. One thing I’ve seen in this book that I haven’t seen in others is an in-depth look at the currently shipping IDEs that support JavaServer Faces. This is especially valuable because such tools can save you time, once you understand the underlying technology they support. In addition to the unique insight this book offers on shipping IDEs, Kito brings to bear his experience as the principal of JSFCentral.com to inform the entire book. This site is a high-quality aggregation of articles, interviews, and, most important, an up-to-the-minute picture of the state of industry and community offerings related to JavaServer Faces. Kito has separate sections that cover components, render kits, implementations, and more. I think you’ll find this site—and this book—extremely valuable as you explore JavaServer Faces programming. ED BURNS JavaServer Faces Specification Lead Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> acknowledgments Most projects are not one-person endeavors, even if they start out that way. Technical books require the talents of an enormous range of people, many of whom donate their free time. (I will, however, take the prize for that particular sacrifice.) Let’s start at the beginning with Clay Anders, the person at Manning who believed that this book was a good idea, well before anyone else was talking about JavaServer Faces. Then, there’s Marjan Bace, Manning’s publisher, who authorized the project, then promptly ripped the first draft of my introduction to shreds. Without Marjan, this book would have already put you to sleep. (If you’re holding open your eyelids with your fingertips right now, blame him.) Next, there’s Jackie Carter—I couldn’t dream of a better developmental editor. Jackie didn’t just critique and guide my work; she was a true partner throughout the process. I’d also like to thank the legions of technical reviewers who let my words consume their evenings without compensation: Roland Bar- cia, Todd Cunningham, Jeff Duska, Carl Hume, Will Forster, Aleksandar Kol- undzija, Jason LeCount, Josh Oberwetter, Michael Nash, Russ Pearlman, Mark Pippins, Matthew Schmidt, Keyur Shah, Sang Shin, and Henri Yandell. Ted Kennedy (rest in peace) and Dave Roberson deserve mention for doing a com- mendable job coordinating the review process. Several members of the JSF Expert Group (Eric Lazarus, Brian Murray, Adam Winer, and especially Michael Nash) helped ensure the technical accu-xxv racy of this book, and Ed Burns (the co-spec lead) wrote an excellent foreword. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> xxvi ACKNOWLEDGMENTS Along the same lines, several vendors gave me insight into their products well before they had public releases available. Beverly Dewitt provided general infor- mation about IBM WebSphere Studio, and Roland Barcia wrote the portion of online extension appendix B about that product (in addition to providing an extremely thorough technical review). Jim Inscore from Sun Microsystems made sure I had access to early releases of Java Studio Creator. Jonas Jacobi and his team at Oracle (Brian Albers, John Fowler, and Adam Winer) went above and beyond the call of duty by not only providing details about JDeveloper but also conducting informal reviews and serving as a general JSF resource. Jonas also wrote about JDeveloper’s JSF support and Oracle’s ADF Faces Components in online extension appendix B. In addition, I enlisted the assistance of my good friend Ed LaCalle for Span- ish translations, as well as my world-traveling brother, John A. Mann II, for Rus- sian translations. My wife Tracey Burroughs provided general technical guidance and support. She also wrote most of appendix E—she has an uncanny knack for detail, and she’s way too brilliant for her own good. There’s also the production team, who worked to create the early-access ver- sion of this book (available in PDF) as well as the print version. Henri Yandell is an extremely meticulous technical editor who made sure that everything I wrote made sense. Liz Welch, the copyeditor, corrected all of my bad grammar and made sure I followed Manning’s guidelines. Susan Forsyth proofread every word, Denis Dalinnik typeset every single page, and Susan Edwards tackled the extremely tedious job of indexing. Finally, Mary Piergies coordinated the pro- duction process. If you have seen this book mentioned on a web site or received a free copy or excerpt, you have Helen Trimes to thank—she’s done an outstanding marketing job. I’d also like to thank a few others at Manning: Lianna J. Wlasiuk, Susan Cap- parelle, Syd Brown, and Iain Shigeoka. And then there are my parents—the strongest and kindest people I know. Whenever I look at where I am in life, I can see a profound imprint of their love and encouragement. All of these people worked hard to make JavaServer Faces in Action a quality product. Lastly, I’d like to thank you, the reader, for buying this book. (Okay, maybe you’re just flipping through it, but that counts for something too.) Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> about this book This book is written for people who currently develop Java web applications— architects, application developers, and front-end developers. From my per- spective, architects worry about the application’s design, which technologies are used, and how the development process will work. Application developers build model objects, application logic, and so on, while front-end developers concentrate on building the GUI, usually with a display technology like Java- Server Pages (JSP) or Velocity. In many shops, these roles are performed by the same people, or those in different roles have overlapping skill sets. JSF is a web application framework like Struts, WebWork, or Tapestry, but this book is accessible even if you haven’t used a web framework before. JavaServer Faces in Action is divided into five parts. The first part covers JSF basics. Chapter 1 explains the motivation behind JSF, examines how it fits into the current landscape, and has the requisite Hello, world! example. This chapter also provides a brief overview of the foundation technologies JSF uses: HTTP, servlets, portlets, and display technologies like JSP. Chapter 2 delves further into JSF by examining its core concepts and explaining in detail how JSF performs its magic. Chapter 3 covers everyday topics like configuration, JSP integration, JavaBean initialization, and navigation. Chapters 4 and 5 cover the standard UI components, and chapter 6 examines internationaliza- tion, validation, and type conversion. All of these chapters explain JSF as a xxvii technology, but also reveal how it is used within tools. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> xxx ABOUT THIS BOOK Component tables In chapters 4 and 5, I use specialized tables to describe JSF UI components. The first is a Component Summary table; here’s an example: Don’t worry about what this means quite yet—the point is that all of the standard JSF UI components are described this way. The idea is to give you all of the basic details about the component in one single table. UI component examples are handled in tables as follows: HtmlOutputText summary Component HtmlOutputText Family javax.faces.Output Possible IDE Display Names Output Text Display Behavior Converts the value to a string and displays it with optional support CSS styles. (If the id or style property is set, encloses the text in a <span> element.) Tag Tibrary HTML JSP Tag <h:outputText> Pass-Through Properties style, title Common Properties id, value, rendered, converter, styleClass, binding (see table 4.2) Property Type Default Value Required? Description escape boolean true No Controls whether or not HTML or XML characters are escaped (displayed literally in a browser). HtmlOutputText example: Text is escaped by default. HTML What are &lt;i&gt;you&lt;/i&gt; looking at? Component Tag <h:outputText value="What are <i>you</i> looking at?"/> Browser DisplayLicensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> ABOUT THIS BOOK xxxi Here, I show the HTML output, the JSP component tag, and the browser display, all in one table. This way, you can easily see how the three different pieces are related. The HTML is displayed first for those who think in terms of HTML. Code annotations I use code annotations because they look much cooler than comments. Here’s an example: public String myAction() { // Do something } Sometimes I’ll expand upon annotations in paragraphs after the code listing, using numbered cueballs like this: b. Callouts I use the typical callouts like NOTE, WARNING, DEFINITION, and so on through- out the text to emphasize specific points that may otherwise get buried in ordi- nary text. Here’s an example: DEFINITION A UI component, or control, is a component that provides specific func- tionality for interacting with an end user. Classic examples include tool- bars, buttons, panels, and calendars. In addition, I use a couple of unique ones: Makes a point that isn’t essential to the current text, but may be useful anyway. Usually, I’m attempting to address related questions you may have. SOAPBOX My own personal opinion. Take these with a grain of salt. Source code and the online extension All of the source code for this book can be downloaded from the book’s web site: http://www.manning.com/mann. The downloadable files contain instructions for installation and compilation. From the same site, book owners can also download This is an action method b BY THE WAYan additional 300 pages of this book, called the online extension, in PDF format. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> xxxii ABOUT THIS BOOK Author Online Manning maintains a forum for us authors to spew our biased views at our beloved readers. The one for JavaServer Faces in Action is available at http:// www.manning.com/mann. If you have any questions about JSF or comments about this book, feel free to drop by. I will personally be checking this forum from time to time, as I’m keenly interested in what you have to say. About the author Kito D. Mann is a consultant specializing in enterprise architecture, mentoring, and development. A programmer since the tender age of 12, he has written sev- eral articles on Java-related technologies, and also speaks at user groups and conferences. He has consulted with several Fortune 500 companies, and has been the chief architect of an educational application service provider. Kito is also the founder of the JSF Central community web site, and a member of JSF 1.2 and JSP 2.1 expert groups. He holds a B.A. in Computer Science from Johns Hopkins University, and lives in Stamford, Connecticut, with his wife, four cats, and two parrots. In his spare time, he enjoys making incomplete compositions with electronic music equipment.Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> Part 1 Exploring JavaServer Faces Part 1 introduces and explores the world of JavaServer Faces programming. We provide an overview of the technology and explain how JSF fits into the current web development landscape. Next, we discuss a sample application, explore how JSF works, and examine its fundamental concepts. This part of the book concludes with chapters that cover all of the standard JSF compo- nents, as well as features like internationalization and validation. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> Introducing JavaServer FacesThis chapter covers ■ What JavaServer Faces is, and what it’s not ■ Foundation technologies (HTTP, servlets, portlets, JavaBeans, and JSP) ■ How JavaServer Faces relates to existing web development frameworks ■ Building a simple application3 Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 6 CHAPTER 1 Introducing JavaServer Faces has a powerful architecture for displaying components in different ways. It also has extensible facilities for validating input (the length of a field, for example) and converting objects to and from strings for display. Faces can also automatically keep your UI components in synch with Java objects that collect user input values and respond to events, which are called backing beans. In addition, it has a powerful navigation system and full support for multiple languages. These features make up JSF’s application infrastruc- ture—basic building blocks necessary for any new system. JavaServer Faces defines the underpinnings for tool support, but the imple- Figure 1.1 IBM’s WebSphere Application Developer (WSAD) has been expanded to support JSF applications in addition to the seemingly endless amount of other technologies it supports. You can visually build JSF applications, and mix-and-match other JSP tag libraries using WSAD’s familiar Eclipse-based environment. mentation of specific tools is left to vendors, as is the custom with Java. You have Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> It’s a RAD-ical world 7 a choice of tools from industry leaders that allow you to visually lay out a web UI in a way that’s quite familiar to users of RAD development tools such as Visual Stu- dio. NET. (Figures 1.1, 1.2, and 1.3 show what Faces development looks like in IDEs from IBM, Oracle, and Sun, respectively.) Or, if you prefer, you can develop Faces applications without design tools. Just in case all of this sounds like magic, we should point out a key difference Figure 1.2 Oracle’s JDeveloper [Oracle, JDeveloper] will have full-fledged support for JSF, complete with an extensive array of UIX components, which will integrate with standard JSF applications. It will also support using JSF components with its Application Development Framework (ADF) [Oracle, ADF]. (This screen shot was taken with UIX components available with JDeveloper 10g, which are the basis of JSF support in the next version of JDeveloper.)between JavaServer Faces and desktop UI frameworks like Swing or the Standard Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 8 CHAPTER 1 Introducing JavaServer Faces Widget Toolkit (SWT): JSF runs on the server. As such, a Faces application will run in a standard Java web container like Apache Tomcat [ASF, Tomcat], Oracle Application Server [Oracle, AS], or IBM WebSphere Application Server [IBM, WAS], and display HTML or some other markup to the client. If you click a button in a Swing application, it will fire an event that you can handle directly in the code that resides on the desktop. In contrast, web browsers Figure 1.3 Sun’s Java Studio Creator [Sun, Creator] is an easy-to-use, visually based environment for building JavaServer Faces applications. You can easily switch between designing JSF pages visually, editing the JSP source, and writing associated Java code in an environment that should seem familiar to users of Visual Studio.NET, Visual Basic, or Delphi.don’t know anything about JSF components or events; they just know how to Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> The technology under the hood 11 use some sort of display technology, such as JavaServer Pages (JSP), as shown in figure 1.4. The display technology is used to define UIs that are composed of components that interact with Java code. Faces applications can also work inside of portlets, which are similar to servlets. JSF’s component architecture uses Java- Beans for exposing properties and event handling. In this section, we briefly describe these technologies and explain how they relate to JSF. If you’re already familiar with Java web development basics and understand how they relate to JSF, you may want to skip this section. 1.2.1 Hypertext Transfer Protocol (HTTP) Diplomats and heads of state come from many different cultures and speak many different languages. In order to communicate, they follow specific rules of ceremony and etiquette, called protocols. Following protocols helps to ensure that they can correspond effectively, even though they come from completely differ- ent backgrounds. Computers use protocols to communicate as well. Following an established set of rules allows programs to communicate regardless of the specific software, hardware, or operating system. The World Wide Web (WWW) started as a mechanism for sharing documents. These documents were represented via the Hypertext Markup Language (HTML) and allowed people viewing the documents to easily move between them by sim- ply clicking on a link. To serve up documents and support this hyperlinking capability, the Hypertext Transfer Protocol (HTTP) was developed. It allowed any web browser to grab documents from a server in a standard way. DEFINITION The Web was originally designed for static content such as academic documents, which do not change often. In contrast, dynamic content, such as stock information or product orders, changes often. Dynamic content is what applications usually generate. HTTP is a simple protocol—it’s based on text headers. A client sends a request to a server, and the server sends a response back to the browser with the requested doc- ument attached. The server is dumb4—it doesn’t remember anything about the cli- ent if another document is requested. This lack of memory means that HTTP is a “stateless” protocol; it maintains no information about the client between requests.4 Web servers have grown to be quite sophisticated beasts, but initially they were pretty simple. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 12 CHAPTER 1 Introducing JavaServer Faces The stateless nature of HTTP means that it’s able to scale well (it is, after all, the protocol of the Internet, and the Internet is a huge place). This property isn’t a problem for the static documents that HTTP was originally developed to serve. But imagine what it’d be like if a valet parked your car but didn’t give you a ticket and didn’t remember your face. When you came back, he’d have a hard time figuring out which car to retrieve. That’s what it’s like to develop an appli- cation in a stateless environment. To combat this problem, there are two possibil- ities: cookies and URL rewriting. They’re both roughly the same as the valet giving you a ticket and keeping one himself. No matter what language you use, if you’re writing a web application, it will use HTTP. Servlets and JSP were developed to make it easier to build applications on top of the protocol. JavaServer Faces was introduced so that developers can forget that they’re using the protocol at all. 1.2.2 Servlets HTTP is great for serving up static content, and web servers excel at that function out of the box. But creating dynamic content requires writing code. Even though HTTP is simple, it still takes some work to write programs that work with it. You have to parse the headers, understand what they mean, and then create new headers in the proper format. That’s what the Java Servlet application program- ming interface (API) is all about: providing an object-oriented view of the world that makes it easier to develop web applications.5 HTTP requests and responses are encapsulated as objects, and you get access to input and output streams so that you can read a user’s response and write dynamic content. Requests are han- dled by servlets—objects that handle a particular set of HTTP requests. A standard J2EE web application is, by definition, based on the Servlet API. Servlets run inside a container, which is essentially a Java application that per- forms all of the grunt work associated with running multiple servlets, associating the resources grouped together as a web application, and managing all sorts of other services. The most popular servlet container is Tomcat [ASF, Tomcat], but J2EE application servers such as IBM WebSphere [IBM, WAS] and the Sun Java System Application Server [Sun, JSAS] provide servlet containers as well. As we mentioned in the previous section, one of the big problems with HTTP is that it’s stateless. Web applications get around this problem through the use of 5 Technically, the Servlet API can be used to provide server functionality in any request/response envi- ronment—it doesn’t necessarily have to be used with HTTP. In this section, we’re referring to the java.servlet.http package, which was designed specifically for processing HTTP requests. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> The technology under the hood 13 sessions—they make it seem as if the users are always there, even if they’re not. Sessions are one of the biggest benefits that the Servlet API provides. Even though behind the scenes they make use of cookies or URL rewriting, the pro- grammer is shielded from those complexities. The Servlet API also provides lots of other goodies, like security, logging, life- cycle events, filters, packaging and deployment, and so on. These features all form the base of JavaServer Faces. As a matter of fact, JSF is implemented as a servlet, and all JSF applications are standard J2EE web applications. JSF takes things a bit further than the Servlet API, though. Servlets cover the basic infrastructure necessary for building web applications. But at the end of the day, you still have to deal with requests and responses, which are properties of the underlying protocol, HTTP. JSF applications have UI components, which are asso- ciated with backing beans and can generate events that are consumed by applica- tion logic. Faces uses the Servlet API for all of its plumbing, but the developer gets the benefit of working at a higher level of abstraction: You can develop web appli- cations without worrying about HTTP or the specifics of the Servlet API itself. 1.2.3 Portlets Most web applications serve dynamic content from a data store—usually a data- base. (Even if the business logic is running on another type of server, like an EJB or Common Object Request Broker Architecture [CORBA] server, eventually some code talks to a database.) Since the early days of the Web, however, there has been a need for software that aggregates information from different data sources into an easy-to-use interface. These types of applications, called portals, were originally the domain of companies like Netscape and Yahoo! However, more and more companies now realize that the same concept works well for aggregating information from different internal data sources for employee use. So a variety of vendors, including heavyweights like IBM, BEA, and Oracle, offer portal products to simplify this task. Each data source is normally displayed in a region within a web page that behaves similarly to a window—you can close the region, customize its behavior, or interact with it independent of the rest of the page. Each one of these regions is called a portlet. Each of these vendors developed a completely different API for writing portlets that work with their portal products. In order to make it easier to develop portlets that work in multiple portals, the JCP developed the Portlet specification [Sun, Portlet], which was released in late 2003. All of the major portal vendors (including Sun, BEA, IBM, and Oracle) and open source organizations like the Apache Software Foundation have announced support for this specification in their portal products. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 16 CHAPTER 1 Introducing JavaServer Faces it with various display technologies. However, because JSF is a standard Java technology, and so is JSP, it’s no surprise that Faces comes with a JSP implementa- tion (via custom tags) right out of the box. And because JSP is the only display technology that must be integrated with JavaServer Faces, most of the examples in this book use JSP as well. 1.3 Frameworks, frameworks, frameworks Earlier, we said that JavaServer Faces is a “framework” for developing web-based UIs in Java. Frameworks are extremely common these days, and for a good rea- son: they help make web development easier. Like most Java web frameworks, JSF enforces a clean separation of presentation and business logic. However, it focuses more on the UI side of things and can be integrated with other frame- works, like Struts. 1.3.1 Why do we need frameworks? As people build more and more web applications, it becomes increasingly obvi- ous that although servlets and JSPs are extremely useful, they can’t handle many common tasks without tedious coding. Frameworks help simplify these tasks. The most basic of these tasks is form processing. HTML pages have forms, which are collection of user input controls like text boxes, lookup lists, and checkboxes. When a user submits a form, all of the data from the input fields is sent to the server. A text field in HTML might look like this: <input maxLength=256 size=55 name="userName" value=""> In a standard servlet application, the developer must retrieve those values directly from the HTTP request like this: String userName = (String)request.getParameter("userName"); This can be tedious for large forms, and because you’re dealing directly with the value sent from the browser, the Java code must also make sure all of the request parameters are valid. In addition, each one of these parameters must be manu- ally associated with the application’s objects. Forms are just one example of tasks that servlets and JSP don’t completely solve. Web applications have to manage a lot of pages and images, and referenc- ing all of those elements within larger applications can become a nightmare if you don’t have a central way of managing it. Management of the page structure is another issue. Although JSP provides a simple mechanism for creating a dynamic page, it doesn’t provide extensive support Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> Frameworks, frameworks, frameworks 17 for composing a page out of smaller, reusable parts. Other fun things that servlets don’t handle include internationalization, type conversion, and error handling. To handle all of these tasks in a simplified manner, several frameworks have emerged. Some of the more popular ones are Struts [ASF, Struts] and WebWork [OpenSymphony, WebWork]. The goal of any framework is to facilitate develop- ment by handling many common tasks. 1.3.2 She’s a Model 2 Basic organization and management services are a necessity for larger web appli- cations, but they need structure as well. Most web frameworks, including JSF, enforce some variation of the Model-View-Controller (MVC) design pattern. To understand exactly what MVC is, let’s look at a driving analogy. When you’re driving down the highway in one direction, there’s usually a median between you and the traffic heading in the opposite direction. The median is there for a good reason—fast traffic moving in opposite directions doesn’t mix too well. Without the median, a rash of accidents would inevita- bly result. Applications have similar issues: Code for business logic doesn’t mix too well with UI code. When the two are mixed, applications are much harder to main- tain, less scalable, and generally more brittle. Moreover, you can’t have one team working on presentation code while another works on business logic. The MVC pattern is the standard solution to this problem. When you watch a story on the news, you view a version of reality. An empirical event exists, and the news channel is responsible for interpreting the event and broadcasting that interpretation. Even though you see the program on your TV, a distinct differ- ence lies between what actually took place, how people doing the reporting understand it, and what you’re seeing on your TV. The news channel is controlling the interaction between the TV program—the view—and the actual event—the model. Even though you may be watching the news on TV, the same channel might be broadcasting via the Internet or producing print publications. These are alternate views. If the pieces of the production weren’t separate, this wouldn’t be possible. In software, the view is the presentation layer, which is responsible for inter- acting with the user. The model is the business logic and data, and the controller is the application code that responds to user events and integrates the model and view. This architecture ensures that the application is loosely coupled, which reduces dependencies between different layers. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 18 CHAPTER 1 Introducing JavaServer Faces Model 2 (shown in figure 1.5) is a variation of MVC that’s specific to web applica- tions. The basic point is that: ■ The model can consist of plain old Java objects (POJOs), EJBs, or some- thing else. ■ The view can be JSPs or some other display technology. ■ The controller is always implemented as a servlet. So if the JSP page contains an error, it doesn’t affect the application code or the model. If there’s an error in the model, it doesn’t affect the application code or the JSP page. This separation allows for unit testing at each layer, and also lets different parties work with the layers independently. For instance, a front-end developer can build a JSP before the business objects and the application code are complete. Portions of some layers can even be integrated before all three have been completed. These benefits are exactly why most frameworks, including JSF, support some variation of the MVC design pattern. 1.3.3 JSF, Struts, and other frameworks Let’s face it: there are a lot of Java web frameworks available. Some of them, like Struts [ASF, Struts] and WebWork [OpenSymphony, WebWork], help with form processing and other issues such as enforcing Model 2, integrating with data Figure 1.5 Most web frameworks use some variation of the Model 2 design pattern.sources, and controlling references to all of the application’s resources centrally via Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> Components everywhere 21 If we take the concepts of kitchen components and apply them to software, we end up with this definition: DEFINITION A software component is a unit of composition with contractually specified interfaces and explicit context dependencies only. A software compo- nent can be deployed independently and is subject to composition by third parties [Szyperski]. The “context dependencies” in a kitchen are things like the room itself, plumb- ing, and electrical circuits. In essence, the context is the container for all of the components. A container is a system that hosts components and provides a set of services that allow those components to be manipulated. Sometimes that manip- ulation is within an IDE (during design time); sometimes it’s in a deployment envi- ronment, like a J2EE server (during runtime). The phrase “deployed independently” means that a component is a self- contained unit and can be installed into a container. Kitchen sinks are individ- ual, self-contained items made to fit into a countertop. When you remodel your kitchen, you hire a contractor, who assembles the components you’ve selected (cabinets, drawers, sink, and so on) into a full- fledged kitchen. When we build software using component architectures, we assemble various components to create a working software system. JSF components, Swing components, servlets, EJBs, JavaBeans, ActiveX con- trols, and Delphi Visual Component Library (VCL) components all fit this defini- tion. But these components concentrate on different things. JSF and Swing components are aimed solely at UI development, while ActiveX and VCL controls may or may not affect the UI. Servlets and EJBs are much more coarse-grained— they provide a lot of functionality that’s more in the realm of application logic and business logic. Because JSF is focused on UI components, let’s narrow our component defini- tion appropriately: DEFINITION A UI component, or control, is a component that provides specific func- tionality for interacting with an end user. Classic examples include tool- bars, buttons, panels, and calendars. If you’ve done traditional GUI development, then the concept of a UI compo- nent should be quite familiar to you. What’s great about JavaServer Faces is that it brings a standard UI component model to the web world. It sets the stage for Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 22 CHAPTER 1 Introducing JavaServer Faces things desktop developers take for granted: a wide selection of packaged UI functionality with extensive tools support. It also opens the door for creating cus- tom components that handle tasks specific to a particular business domain—like a report viewer or an interest calculator. 1.5 Hello, world! Now that you have a basic understanding of the problems JavaServer Faces is meant to solve, let’s begin with a simple Faces application. This section assumes you’re familiar with Java web applications and JSP. (For more about these tech- nologies, see section 1.2 for an overview.) We’ll dissect a simple HTML-based web application that has two pages: hello.jsp and goodbye.jsp. The hello.jsp page does the following: ■ Displays the text “Welcome to JavaServer Faces!” ■ Has a single form with a text box that requires an integer between 1 and 500 ■ Stores the last text box value submitted in a JavaBean property called numControls ■ Has a grid underneath the text box ■ Has a button labeled “Redisplay” that when clicked adds numControls output UI components to the grid (clearing it of any previous UI components first) ■ Has a button labeled “Goodbye” that displays goodbye.jsp if clicked The goodbye.jsp page does the following: ■ Displays the text “Goodbye!” ■ Displays the value of the JavaBean property numControls JSF performs most of the work of our Hello, world! application, but in addition to the JSP pages, there are a few other requirements: ■ The HelloBean backing bean class ■ A Faces configuration file ■ A properly configured deployment descriptor Some tools will simplify creation of some or all of these requirements, but in this section, we’ll examine the raw files in detail. Before we get into those details, let’s see what Hello, world! looks like in a web browser. The application starts with hello.jsp, as shown in figure 1.7. The text box on this page is associated with a JavaBean property of the HelloBean class; Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> Hello, world! 23 when someone enters a value into this box, the property will be updated auto- matically (if the value is valid). If you enter the number “64” into the text box and click the Redisplay button, the page redisplays as shown in figure 1.8—a total of 64 UI components are dis- played in the grid. If you clear the text box and click the Redisplay button, you’ll get a validation error, as shown in figure 1.9. You’ll also get a validation error if Figure 1.7 The Hello, world! application before any data has been submitted. Figure 1.8 The Hello, world! application after you enter "64" and click the Redisplay button. The grid is populated with 64 UI components. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 26 CHAPTER 1 Introducing JavaServer Faces fact, figures 1.1 to 1.3 are screen shots of designing hello.jsp in different IDEs. These IDEs ultimately generate something like listing 1.1 (and, of course, you can create JSF pages by hand). <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <f:view> <html> <head> <title> JSF in Action - Hello, world! </title> </head> <body> <h:form id="welcomeForm"> <h:outputText id="welcomeOutput" value="Welcome to JavaServer Faces!" style="font-family: Arial, sans-serif; font-size: 24; color: green;"/> <p> <h:message id="errors" for="helloInput" style="color: red"/> </p> <p> <h:outputLabel for="helloInput"> <h:outputText id="helloInputLabel" value="Enter number of controls to display:"/> </h:outputLabel> <h:inputText id="helloInput" value="#{helloBean.numControls}" required="true"> <f:validateLongRange minimum="1" maximum="500"/> </h:inputText> </p> <p> <h:panelGrid id="controlPanel" binding="#{helloBean.controlPanel}" columns="20" border="1" cellspacing="0"/> </p> <h:commandButton id="redisplayCommand" type="submit" value="Redisplay" actionListener="#{helloBean.addControls}"/> <h:commandButton id="goodbyeCommand" type="submit" value="Goodbye" Listing 1.1 hello.jsp: opening page of our Hello, world! application (browser output shown in figures 1.7–1.10) JSF tag libraries b Tag enclosing all JSF tags c HtmlForm component d HtmlOutputText component e HtmlMessage component f HtmlOutputLabel with child HtmlOutputText g HtmlInputText component h HtmlPanelGrid component i HtmlCommandButton components j action="#{helloBean.goodbye}" immediate="true"/> </h:form> Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> Hello, world! 27 </body> </html> </f:view> First, we import the core JavaServer Faces tag library. This library provides cus- tom tags for such basic tasks as validation and event handling. Next, we import the basic HTML tag library, which provides custom tags for UI components like text boxes, output labels, and forms. (The prefixes “f ” and “h” are suggested, but not required.) The <f:view> custom tag must enclose all other Faces-related tags (from both the core tag library and the basic HTML tag library). The <h:form> tag represents an HtmlForm component, which is a container for other components and is used for posting information back to the server. You can have more than one HtmlForm on the same page, but all input controls must be nested within a <h:form> tag. The <h:outputText> tag creates an HtmlOutputText component, which simply dis- plays read-only data to the screen. This tag has an id attribute as well as a value attribute. The id attribute is optional for all components; it’s not required unless you need to reference the component somewhere else. (Components can be ref- erenced with client-side technologies like JavaScript or in Java code.) The value attribute specifies the text you want to display. The <h:message> tag is for the HtmlMessage component, which displays validation and conversion errors for a specific component. The for attribute tells it to display errors for the control with the identifier helloInput, which is the identifier for the text box on the page (h). If no errors have occurred, nothing is displayed. The <h:outputLabel> tag creates a new HtmlOutputLabel component, which is used as a label for input controls. The for property associates the label with an input control, which in this case is helloInput (h). HtmlOutputLabels don't display anything, so we also need a child HtmlOutputText (created by the nested <h:outputText> tag) to display the label's text. The <h:inputText> tag is used to create an HtmlInputText component that accepts text input. Note that the value property is "#{helloBean.numControls}", which is a JSF Expression Language (EL) expression referencing the numControls property of a backing bean, called helloBean. (The JSF EL is a based upon the EL intro- duced with JSP 2.0.) Faces will automatically search the different scopes of the web application (request, session, application) for the specified backing bean. In this case, it will find a bean stored under the key helloBean in the application’s session. The b c d e f g hvalue of the component and helloBean’s numControls property are synchronized Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 28 CHAPTER 1 Introducing JavaServer Faces so that if one changes, the other one will change as well (unless the text in the HtmlInputText component is invalid). Input controls have a required property, which determines whether or not the field must have a value. In this case, required is set to true, so the compo- nent will only accept non-empty input. If the user enters an empty value, the page will be redisplayed, and the HtmlMessage (f) component will display an error message, as shown in figure 1.9. JSF also supports validators, which are responsible for making sure that the user enters an acceptable value. Each input control can be associated with one or more validators. The <f:validateLongRange> tag registers a LongRange validator for this HtmlInputText component. The validator checks to make sure that any input is a number between 1 and 500, inclusive. If the user enters a value outside that range, the validator will reject the input, and the page will be redisplayed with the HtmlMessage (f) component displaying the error message shown in figure 1.10. Whenever the user’s input is rejected, the object referenced by the HtmlInput- Text component’s value property will not be updated. An HtmlPanelGrid component is represented by the <h:panelGrid> tag. HtmlPanel- Grid represents a configurable container for other components that is displayed as an HTML table. Any JSF component can be associated directly with a backing bean via its JSP tag’s binding attribute. (Some tools will do this automatically for all of the com- ponents on a page.) The tag’s binding attribute is set to "#{helloBean.control- Panel}". This is a JSF EL expression that references helloBean’s controlPanel property, which is of type HtmlPanelGrid. This ensures that helloBean always has access to the HtmlPanelGrid component on the page. The <h:commandButton> specifies an HtmlCommandButton component that’s displayed as an HTML form button. HtmlCommandButtons send action events to the applica- tion when they are clicked by a user. The event listener (a method that executes in response to an event) can be directly referenced via the actionListener prop- erty. The first HtmlCommandButton’s actionListener property is set to "#{hello- Bean.addControls}", which is an expression that tells JSF to find the helloBean object and then call its addControls method to handle the event. Once the method has been executed, the page will be redisplayed. The second HtmlCommandButton has an action property set instead of an actionListener property. The value of this property, "#{helloBean.goodbye}", references a specialized event listener that handles navigation. This is why clicking on this button loads the goodbye.jsp page instead of redisplaying the hello.jsp i jpage. This button also has the immediate property set to true, which tells JSF to Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> Hello, world! 31 directly to the HTML. (Most of the standard HTML components expose HTML- specific properties that are simply passed through to the browser.) Each cell in the table is the output of an HtmlOutputText component that was added to the HtmlPanelGrid in Java code, in response to a user clicking the Redisplay button. (In the real HTML, there are 64 cells because that’s the number that was entered into the text box; we left some of them out of the listing because, well, that’s a lot of lot of extra paper!) We’ll examine the Java code soon enough, but let’s look at goodbye.jsp first. 1.5.2 Dissecting goodbye.jsp The goodbye.jsp page, shown in figure 1.11, is displayed when the user clicks the Goodbye button. The page (listing 1.3) contains some of the same elements as the hello.jsp page: imports for the JSF tag libraries, an HtmlForm component, and HtmlOutputText components. One of the HtmlOutputText components references the same helloBean object as the previous page. This works fine because the object lives in the application’s session and consequently survives between page requests. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %> <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %> <f:view> <html> <head> <title> JSF in Action - Hello, world! </title> </head> <body> <h:form id="goodbyeForm"> <p> <h:outputText id="welcomeOutput" value="Goodbye!" style="font-family: Arial, sans-serif; font-size: 24; font-style: bold; color: green;"/> </p> <p> <h:outputText id="helloBeanOutputLabel" value="Number of controls displayed:"/> <h:outputText id="helloBeanOutput" Listing 1.3 goodbye.jsp: Closing page of our Hello, world! application (the browser output is shown in figure 1.11) Same backing value="#{helloBean.numControls}"/> </p> bean as hello.jsp Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 32 CHAPTER 1 Introducing JavaServer Faces </h:form> </body> </html> </f:view> There’s nothing special about the HTML generated by this page that we didn’t cover in the previous section, so we’ll spare you the details. What’s important is that we were able to build a functional application with validation and page nav- igation with only two simple JSPs. (If we didn’t want to show navigation, the first page would have been good enough.) Now, let’s look at the code behind these pages. 1.5.3 Examining the HelloBean class Both hello.jsp and goodbye.jsp contain JSF components that reference a backing bean called helloBean through JSF EL expressions. This single JavaBean con- tains everything needed for this application: two properties and two methods. It’s shown in listing 1.4. package org.jia.hello; import javax.faces.application.Application; import javax.faces.component.html.HtmlOutputText; import javax.faces.component.html.HtmlPanelGrid; import javax.faces.context.FacesContext; import javax.faces.event.ActionEvent; import java.util.List; public class HelloBean { private int numControls; private HtmlPanelGrid controlPanel; public int getNumControls() { return numControls; } public void setNumControls(int numControls) { this.numControls = numControls; } Listing 1.4 HelloBean.java: The simple backing bean for our Hello, world! application No required superclass b Property referenced on both JSPs cLicensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> Hello, world! 33 public HtmlPanelGrid getControlPanel() { return controlPanel; } public void setControlPanel(HtmlPanelGrid controlPanel) { this.controlPanel = controlPanel; } public void addControls(ActionEvent actionEvent) { Application application = FacesContext.getCurrentInstance().getApplication(); List children = controlPanel.getChildren(); children.clear(); for (int count = 0; count < numControls; count++) { HtmlOutputText output = (HtmlOutputText)application. createComponent(HtmlOutputText.COMPONENT_TYPE); output.setValue(" " + count + " "); output.setStyle("color: blue"); children.add(output); } } public String goodbye() { return "success"; } } Unlike a lot of other frameworks, JSF backing beans don’t have to inherit from a specific class. They simply need to expose their properties using ordinary Java- Bean conventions and use specific signatures for their event-handling methods. The numControls property is referenced by the HtmlInputText component on hello.jsp and an HtmlOutputText component on goodbye.jsp. Whenever the user changes the value in the HtmlInputText component, the value of this property is changed as well (if the input is valid). The controlPanel property is of type HtmlPanelGrid, which is the actual Java class created by the <h:panelGrid> tag used in hello.jsp. That tag’s binding attribute associates the component instance created by the tag with the control- Panel property. This allows HelloBean to manipulate the actual code—a task it happily performs in e. Property bound to HtmlPanelGrid d Executed by Redisplay HtmlCommandButton e Executed by Goodbye HtmlCommandButton f b c dLicensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 36 CHAPTER 1 Introducing JavaServer Faces Declaring navigation is as simple as declaring a managed bean. Each JSF application can have one or more navigation rules. A navigation rule specifies the possible routes from a given page. Each route is called a navigation case. The listing shows the navigation rule for Hello, world!’s hello.jsp page (d). hello.jsp has a Goodbye button that loads another page, so there is a single navigation case: if the outcome is "success", the page goodbye.jsp will be displayed. This outcome is returned from helloBean’s goodbye method, which is executed when a user clicks the Goodbye button. It’s worthwhile to point out that some aspects of JSF configuration, particu- larly navigation, can be handled visually with tools. Now, let’s see how our appli- cation is configured at the web application level. 1.5.5 Configuration with web.xml All J2EE web applications are configured with a web.xml deployment descriptor; Faces applications are no different. However, JSF applications require that you specify the FacesServlet, which is usually the main servlet for the application. In addition, requests must be mapped to this servlet. The deployment descriptor for our Hello, world! application is shown in listing 1.6. You can expect some tools to generate the required JSF-related elements for you. <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3/ /EN" "http://java.sun.com/dtd/web-app_2_3.dtd"> <web-app> <display-name>Hello, World!</display-name> <description>Welcome to JavaServer Faces</description> <servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> </web-app> Listing 1.6 web.xml: The deployment descriptor for our Hello, world! application JSF servlet Standard JSF mappingLicensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> Summary 37 That’s it—Hello, world! dissected. You can see that JSF does a lot of things for you—validation, event handling, navigation, UI component management, and so on. As we walk through the various aspects of JSF in more detail, you’ll gain a deep understanding of all of the services it provides so that you can concentrate on building the application and avoid that joyous thing they call grunt work. 1.6 Summary JavaServer Faces (JSF, or “Faces”) is a UI framework for building Java web appli- cations; it was developed through the Java Community Process (JCP) and will become part of Java 2 Enterprise Edition (J2EE). One of the main goals of Faces is to bring the RAD style of application development, made popular by tools like Microsoft Visual Basic and Borland Delphi, to the world of Java web applications. JSF provides a set of standard widgets (buttons, hyperlinks, checkboxes, and so on), a model for creating custom widgets, a way to process client-generated events on the server, and excellent tool support. You can even synchronize a UI component with an object’s value, which eliminates a lot of tedious code. All JSF applications are built on top of the Servlet API, communicate via HTTP, and use a display technology like JSP. JavaServer Faces applications don’t require JSP, though. They can use technologies like XML/XSLT, other template engines, or plain Java code. However, Faces implementations are required to provide basic integration with JSP, so most of the examples in this book are in JSP. The component architecture of Faces leverages JavaBeans for properties, fun- damental tool support, an event model, and several other goodies. JSF is consid- ered a web application framework because it performs a lot of common development tasks so that developers can focus on more fun things like business logic. One of the key features is support of the Model 2 design pattern, which enforces separation of presentation and business logic code. However, Faces focuses on UI components and events. As such, it integrates quite nicely with the other frameworks like Struts, and overlaps quite a bit with the functionality of higher-level frameworks. The Hello, world! example demonstrates the basic aspects of a JavaServer Faces application. It shows how easy it is to define a UI with components like text boxes, labels, and buttons. It also shows how Faces automatically handles input validation and updating a JavaBean based on the value of a text control. In the next chapter, we’ll look at the core JSF concepts and examine how the framework masks the request/response nature of HTTP.Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> JSF fundamentalsThis chapter covers ■ Key terms and concepts ■ How JSF processes an incoming request ■ The JSF expression language 38 Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> The key pieces of the pie 41 logic. Action methods can do everything event listeners can, but they also return an outcome that is used by the navigation system. Finally, the navigation system uses this outcome to select the next view to display to the user. Most of the concepts in this diagram generate a message or an event. This is how JSF applications communicate. Events represent user input or application operations. Messages indicate errors or application notifications. You may have noticed that events, messages, and model objects are passive from the perspective of JSF. In other words, they don’t do anything—some other class is always operating on them. This is an important point for model objects, because it means that the model doesn’t know about the user interface. This is part of how JSF enforces an MVC-style architecture. Now that you have an idea about what these terms mean, and how they relate to one another, let’s examine each one in detail. 2.1.1 User interface components User interface (UI) components (also called controls, or simply components) focus on interacting with an end user. Visual Basic has UI components, and so does Swing, so what’s unique about Faces components? Like Swing controls, they’re built on top of JavaBeans. This means they have properties, methods, and events, plus inherent support for IDEs. Unlike Swing, they’re specifically designed for the unique constraints of web applications, and they live on the server side, not the client. This is important, because most web interfaces aren’t built with components—they just output markup, like HTML. Packaging UI elements as a component (like a toolbar or a calendar) makes development easier because the core functions are encapsulated within a reus- able piece of code. For example, if you use a calendar control you don’t have to develop a complicated combination of HTML, CSS, and graphics to make it look just right. You may have to manipulate some properties, such as the colors, or the default date, but all the hard work has already been completed by the com- ponent’s developer. There isn’t even a need to write a lot of code to integrate it with your application—just associate it with a JavaBean property of a backing bean (described later), and you’re done. If you think about it, there are a bunch of different ways a calendar can be represented. The most common way is to show a month at a time, with a little box for each day of the month. But a calendar could also be represented as three drop-down boxes: one each for the day, month, and year. The way a component looks is how it is rendered. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 42 CHAPTER 2 JSF fundamentals Regardless of how it rendered, a calendar has the same basic functionality and an intrinsic set of properties, like its colors, the default date, and the range of dates you want to display. A calendar component represents what the calendar does, not what it looks like. Such behavior is called renderer neutral, because it is the same regardless of how the component is rendered. This distinction is key when you’re developing components in Java, but as a front-end or application developer, you can use components with interfaces that are tailored for a specific client environment. (For example, an HtmlInputText component has HTML-spe- cific properties like accessKey and style, even though it doesn’t technically han- dle rendering itself.) One of the key differences between web-based and desktop-based compo- nents is that the former never directly interact with the user’s machine. If you fill out a form incorrectly in a desktop application and click OK, the page isn’t redis- played—the program just tells you what the errors were (at least you hope it does!). All of the values on the form just stay there. In web applications, the page is often redisplayed with error messages, but the application has to make it look as if it wasn’t redisplayed at all. In other words, the components have to remem- ber their values, or state. JSF components handle this for you automatically. Faces components can remember their values between requests because the framework maintains a tree of the UI components for a given page. This compo- nent tree, called the view, is JSF’s internal representation of the page, and it allows parent-child relationships, such as having a form that contains a label, a text field, and a panel with two nested buttons, as shown in figure 2.2. Using “view” instead of “page” underscores the fact that the user’s representation doesn’t always have to be an HTML web page. However, for simplicity, we’ll use the two interchangeably. Each component in the tree is identified with a component identifier. The com- ponent identifier can be set by a developer; if none is set, it will be generated automatically. In addition, components can be associated with one another via named relationships like “header” or “footer”—these are called facets. UI compo- nents can also support accessibility properties that make them easier to access for users with disabilities. UI components raise the abstraction bar, bringing a whole new level of flexi- bility to web development. Building UIs with JSF is more about assembling and configuring components than writing tedious code in different technologies (HTML, CSS, JavaScript, and so on). And all of these components can be refer- enced and manipulated both in code, via GUI designers, and declaratively (with a display technology like JSP). Faces includes several standard components such Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> The key pieces of the pie 43 as labels, hyperlinks, text boxes, list boxes, checkboxes, radio buttons, panels, and data grids. We cover these in chapters 4 and 5; custom component develop- ment is covered in part 4 and online extension part 5. 2.1.2 Renderers Faces UI components aren’t always responsible for their own rendering. When components render themselves, it’s called the direct implementation model, but JSF also supports the delegated implementation model, which allows separate classes to handle the process. Those classes are called, surprisingly enough, renderers. Renderers are organized into render kits, which usually focus on a specific type of output. JSF ships with a standard render kit for HTML 4.01, but a render kit could generate a different HTML look and feel (or “skin”), Wireless Markup Lan- guage (WML), Scalable Vector Graphics (SVG), or it could communicate with an applet, Java application, or an entirely different type of client. You can think of a renderer as a translator between the client and the server worlds. On the way from the server, it handles encoding, which is the process of creating a representation of a component that the client understands. When JSF receives a response from the user, the renderer handles decoding, which is the Figure 2.2 UI components are managed on the server in a view, or component tree. The components can be wired directly to the values of JavaBean properties. Components are rendered to the client in HTML (or in some other display language).process of extracting the correct request parameters and setting a component’s value based on those parameters. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 46 CHAPTER 2 JSF fundamentals bean classes automatically when you create a new page. They may also refer to them as “web forms” or “code-behind,” which underscores their conceptual sim- ilarity to code-behind files in the ASP.NET world (behind the scenes, they’re quite different). JSF allows you to declaratively associate backing beans with UI components. By declaratively, we mean with markup instead of code (you can do this in code as well). You associate a component with a backing bean via the JSF expression lan- guage (EL), which is similar to the JSP 2.0 and JSTL expression languages. You can use a JSF EL expression to point to a specific backing bean property some- where in your application. For example, look at this snippet from the Hello, world! example: <h:outputText id="helloBeanOutput" value="#{helloBean.numControls}"/> This code snippet hooks up an HtmlOutputText component’s value directly to the numControls property of an object called helloBean. Whenever the value of the component changes, the helloBean.numControls property changes as well. The same is true if the helloBean.numControls property changes first; the two are automatically kept in sync. This a key feature of JSF, and it’s how you will typically associate the backing bean properties with the UI component values. You can also associate, or bind, a backing bean property directly with a server- side component instance. This is useful when you want to manipulate a compo- nent with Java code, which is the type of processing sometimes performed by event listeners. For example, the Hello, world! application has an HtmlPanelGrid component instance that is bound to the HelloBean backing bean property: <h:panelGrid id="controlPanel" binding="#{helloBean.controlPanel}" columns="20" border="1" cellspacing="0"/> Here, the component’s binding property uses a JSF EL expression to associate it with the HelloBean property controlPanel, which is of type HtmlPanelGrid. Because the backing bean has a reference to the actual component, it can manip- ulate it in code: ... List children = controlPanel.getChildren(); children.clear(); ... This code, located in a HelloBean event listener method, retrieves the child com- ponents from controlPanel and removes them all. These changes will appear the next time the page is displayed to the user. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> The key pieces of the pie 47 If you’re used to thinking that JavaBeans are only useful as Value Ob- jects (objects with only properties), it’s important to remember that they can be so much more than that. Backing beans are full-fledged Java- Beans that contain properties, but also contain event listener methods that can act on those properties. They can optionally be associated di- rectly with UI components, so you have the choice of directly manipulat- ing the view if necessary. A single view can have one or more backing beans, and tools will sometimes automatically create bindings from UI components to their corresponding back- ing bean properties. Backing beans will often talk to model objects—helper classes, which access ser- vices like databases, web services, and EJBs or perform application logic, or rep- resent things like users, user preferences, reports, and trades. Model objects, like backing beans, can be associated directly with a component’s value using JSF expressions as well. For example, you may want to associate an input control with a User object’s name property. Model objects aren’t bound directly to UI compo- nents, though, because they don’t know anything about the UI. So that application developers don’t spent a lot of time writing boring code that creates backing beans and model objects, JSF provides a declarative mecha- nism for creating them, called the Managed Bean Creation facility. It allows you to specify which objects will be available throughout the lifecycle of the application. Here’s another snippet from Hello, world!: <managed-bean> <managed-bean-name>helloBean</managed-bean-name> <managed-bean-class>com.virtua.jsf.sample.hello.HelloBean </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> This tells JSF to create an instance of the HelloBean class called helloBean, and store it in the user’s session. This little snippet is all that’s required to make an object available for integration with UI components. Any objects that use this facility are called managed beans. Understanding how JSF interacts with backing beans and model objects is an essential part of building Faces applications. One of the framework’s primary goals is to ease the burden of integrating the UI with the model, and the more you work with it, the more features you’ll find that make that goal a reality. You can find references to backing beans throughout this book; we develop BY THE WAYsome in chapter 13. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 48 CHAPTER 2 JSF fundamentals 2.1.5 Converters When users interact with a JSF application, they interact with the output of ren- derers, which create specific representations that make sense for a particular cli- ent (like a web browser). In order to do this, renderers must have specific knowledge about the components they display. But components can also be asso- ciated with backing bean properties. Those properties can be anything—a String representing a name, a Date representing a birth date, or a FooBarBazz rep- resenting a foo property. Because there are no constraints on the type, a renderer can’t know beforehand how to display the object. This is where converters come in—they translate an object to a string for dis- play, and from an input string back into an object. A single converter can be associated with any control. JSF ships with converters for common types like dates and numbers, but you, or third parties, can develop additional ones as well. Renderers (or components themselves) usually use converters internally during encoding or decoding. Converters also handle formatting and localization. For example, the DateTime converter can format a Date object in a short, medium, long, or full style. For any given style, it will display the date in a way that makes sense in the user’s locale. Here’s how you register a converter on an HtmlOutputText component: <h:outputText value="#{user.dateOfBirth}"> <f:convert_datetime type="both" dateStyle="full"/> </h:outputText> Let’s suppose the user’s birth date is May 4, 1942. The HtmlOutputText component would display the string “05/04/42” if the user is from the United States but display “04/05/42” if the user is from Canada. This is shown graphically in figure 2.3.Figure 2.3 A converter translates an object to and from a string for display. It also handles formatting and supports various languages. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> The key pieces of the pie 51 In addition to using listener methods for value-change events, you can regis- ter event listener classes that implement an interface. Most of the time, however, associating a specific method with a component is sufficient. Action events Action events are triggered when a user interacts with a control that represents a command, or a user gesture. Components that generate action events, also called action sources, include controls such as buttons or hyperlinks. Action events are handled by action listeners. There are two types of action listeners: those that affect navigation, and those that don’t. Action listeners that affect navigation typically perform some process- ing and then return a logical outcome that is used by JSF’s navigation system to select the next page (which may actually be the same page that’s currently being viewed). Listeners that don’t affect navigation usually manipulate components in the current view, or perform some processing that changes model object or back- ing bean properties, but doesn’t alter the current page the user is accessing. Consequently, the page is usually redisplayed after the listener finishes executing. Technically, all navigation is handled by a single action listener. This listener automatically handles any action events fired by a component, so it doesn’t need to be registered manually. By default, this action listener delegates all of its work to action methods in your backing beans, so you can have different action methods handle different parts of your application. Typically, most of your application logic will be located in these methods. (The action listener is pluggable, so it’s possible to replace it with one that doesn’t use action methods at all.) When a component fires an action event, this default action listener deter- mines its outcome string—"mainmenu", "success", or "failure", for example. There are two basic types of outcomes: static and dynamic. Static outcomes are hardcoded strings that are declared with the component or set in code: <h:commandButton type="submit" value="Login" action="success" immediate="true"/> In this example, the static outcome of "success" will be generated when the user clicks on this HtmlCommandButton and generates an action event—no action method will be called. Dynamic outcomes are strings returned by action methods themselves—an action method might return a different outcome depending on whatever application logic it performs. The action listener looks for an action method whenever you use a JSF EL expression in the action property. Here’s an HtmlCommandButton that executes an action method instead: Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 52 CHAPTER 2 JSF fundamentals <h:commandButton type="submit" value="Login" action="#{loginForm.login}"/> When a user clicks on this button, an action event is fired, and the following method is executed in response to the event: public class LoginForm { ... public String login() { if (...) // login is successful { return "success"; } else { return "failure"; } } ... } Based on some voodoo application logic, this action method returns an outcome of either "success" or "failure". LoginForm is a backing bean whose properties are wired up to input control values on the page, and is configured via the Man- aged Bean Creation facility. My example has voodoo logic, but your action methods can manipulate JSF components, model objects, or add messages. They can also do other fun tasks, such as performing a redirect, rendering a response (a graphic or some binary type of data), adding events, and talking to databases, EJB servers, or web ser- vices. The action listener uses the outcome of an action method to hook into the navigation system and determine what page to choose next. When you need to execute application logic that is not associated with naviga- tion, you can associate an action listener method with a component. Unlike action methods, action listener methods have access to the component that fired the event as well. Take a look at this example: <h:commandButton id="redisplayCommand" type="submit" value="Redisplay" actionListener="#{myForm.doIt}"/> Like the previous example, when a user clicks on this HtmlCommandButton, an action event is fired. This time, however, the action listener method is executed instead of the action method:public void doIt(ActionEvent event) { Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> The key pieces of the pie 53 HtmlCommandButton button = (HtmlCommandButton)event.getComponent(); button.setValue("It's done!"); } This method changes the value (label) of the button that fired the event—not terribly useful. What’s important, however, is its method signature. Instead of accepting zero parameters and returning an outcome string, action listener methods accept an ActionEvent as a parameter and don’t return an outcome at all. After this method executes, the page will be redisplayed, incorporating any changes made by the method. Usually, you use action listener methods for changes that affect the current view. Like value-change listeners, you can also implement an action listener using a Java interface, although in most cases using a method in an existing backing bean is sufficient. Data model events Data model events are triggered when a data-aware component processes a row. The most common way to trigger this event is through a component that dis- plays a selectable list of items, such as HtmlDataTable, which is the quintessential “data grid” component. Unlike value-change or action event listeners, data model event listeners must implement a Java interface. Data model events are a little different than the other events because they’re not actually fired by a UI component. Instead, they’re fired by a DataModel instance, which is a model object used internally by data-aware components. DataModel objects are wrappers for lists, arrays, result sets, and other data sources. Since the event is technically fired by a model object instead of a compo- nent, you can’t register a listener on the component itself in JSP. You have to reg- ister it in Java code instead: FacesContext facesContext = FacesContext.getCurrentInstance(); dataTable = (HtmlDataTable)facesContext.getApplication().createComponent( HtmlDataTable.COMPONENT_TYPE); DataModel myDataModel = new ResultSetDataModel(myResultSet); myDataModel.addDataModelListener(new DataModelListener() { public void rowSelected(DataModelEvent e) { FacesContext.getCurrentInstance().getExternalContext(). log("row selected:" + e.getRowIndex()); } }); dataTable.setValue(myDataModel);Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 56 CHAPTER 2 JSF fundamentals Messages don’t necessarily have to indicate errors; they can be informational as well. For example, an action listener method could add a message indicating that a new record was successfully added. The message itself can either be associ- ated with a specific component (for input errors) or no component at all (for application messages). You can display errors associated with a specific component by using the HtmlMessage component. You may remember HtmlMessage from the Hello, world! application: <h:message id="errors" for="helloInput" style="color: red"/> This tag displays all errors that were generated for the helloInput input component (which must be declared on the same page). You can also display all messages, or those not associated with a specific component, using the HtmlMessages component. Messages provide a convenient way to communicate errors and other hap- penings to the user. They’re an integral part of JSF’s validation and type conver- sion features—any time a validator encounters an incorrect value or a converter processes an incorrect type, it generates an error message. They’re also an excel- lent way for you to communicate information to a user without worrying about how it is being displayed; simply create a new message in your action listener method, and the view will display it for you. You can find out how to customize the standard application messages in chapter 6, and how to create them in Java code in chapter 11. 2.1.8 Navigation All of the concepts we’ve discussed so far have been related to interaction on a single page. Writing web applications would be a piece of cake if they were con- fined to a single page, but in reality that’s not the case. Web applications have multiple pages, and we must have some way to move between them. The act of moving from one page to another is called navigation. Faces has a pretty elegant navigation system. The navigation handler is respon- sible for deciding what page to load based on the logical outcome of an action method. For any given page, a navigation rule defines what outcomes are under- stood, and what pages to load based on those outcomes.1 Each specific mapping between an outcome and a page is called a navigation case. The rules are defined 1 This is the way the default navigation handler works. JSF allows you, or other developers, to plug in new ones that behave differently. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> The Request Processing Lifecycle 57 in a JSF configuration file. Here is a navigation rule with the two cases for the page login.jsp—the "success" and "failure" outcomes: <navigation-rule> <from-view-id>/login.jsp</from-view-id> <navigation-case> <from-outcome>success</from-outcome> <to-view-id>/mainmenu.jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>failure</from-outcome> <to-view-id>/login.jsp</to-view-id> </navigation-case> </navigation-rule> As you can see, each case maps the outcome to a specific page—no code required. This is a handy feature of JSF that should look familiar if you’ve used frameworks like Struts. All navigation cases are usually kept in a single place, which means any changes can be made in a central location instead of across sev- eral pages. Navigation is covered in detail in chapter 3, and you can find many examples in parts 2 and 3. Now that we’ve looked at the key pieces of the JSF pie, let’s see how these con- cepts come into play when the framework processes an incoming request. 2.2 The Request Processing Lifecycle We’ve been talking about how JSF simplifies web programming with compo- nents, events, listeners, and several other nifty concepts. So why is this section about processing requests? In order for you to understand how the framework masks the underlying request processing nature of the Servlet API, it helps to analyze how Faces processes each request. This will allow you to build better applications because you’ll know exactly what operations take place, and when. If you’re a front-end developer who tends to avoid such details, you can skip this section. You can always refer back to it if necessary. In this chapter we describe how JSF responds to requests that Faces generates itself. In other words, the request was generated by a page with JSF components, and the response will have JSF components on it as well. (It’s entirely possible to return a page with JSF components on it, even if the initial request wasn’t generated by JSF; see chapter 14 for more about different request processing scenarios.) Figure 2.4 is a state diagram showing what happens when JSF processes an incoming request from a client—the JSF Request Processing Lifecycle. This process begins as soon as a request is received by the JSF servlet (remember, JSF is built Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 58 CHAPTER 2 JSF fundamentals Figure 2.4 The Request Processing Lifecycle. Flows with dotted lines are optional. JSF cycles through several phases as it processes each request. After each phase, event listeners are called. Listeners can either continue as normal, report errors and skip to the Render Response phase, or generate the response themselves. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> The Request Processing Lifecycle 61 This is the important part—these are the actual parameters JSF processes (the ampersand is used to separate parameters, and “%3A” translates to a colon [“:”]). The first parameter has a name of “welcomeForm:helloInput” and a value of "64", which is the number entered into the browser. The second parameter has a name of “welcomeForm:redisplayCommand” and value of “Redisplay”. The final parameter is simply called “welcomeForm” and has a value of “welcomeForm”. We’ll see how these parameters are handled in the following sections. Once JSF receives this HTTP request, it creates and populates an instance of javax.faces.context.FacesContext. This class represents the current state of the request, and has hooks to all aspects of the underlying servlet request object. It’s where your event listeners can get a handle to the current view, add mes- sages, log events, and so on. JSF uses this object as the basis for the Request Pro- cessing Lifecycle. We describe each phase in the following sections. 2.2.1 Phase 1: Restore View A view represents all of the components that make up a particular page. It can be stored on the client (usually in a hidden field on a browser) or on the server (usu- ally in the session). In this example, it’s stored on the server, which is the default. Each view is composed of a tree of components, and has a unique identifier. This view identifier is the same as the extra path info for the request.2 So, for the path referenced by B in listing 2.1, “/jia-hello-world/faces/hello.jsp”, the view identi- fier is “/hello.jsp”—everything after the servlet name. Because this request was sent when a user clicked on a button in hello.jsp, the page that’s sending the request is the same as the page that’s receiving it. The pro- cess of a page posting back to itself is called postback. If you’re accustomed to web frameworks like Struts that segregate application code into separate Action classes that are mapped to URLs, this may seem a bit strange. In these types of frameworks, the URL is sort of like a course-grained event that says “perform this action.” JSF events represent more fine-grained events such as “user executed this command” or “user changed the value of this control.” The important thing about these events is that they’re related to the last page that was requested. When a JSF application receives a request from an existing page, it has to figure out what page sent the request so that it can identify which events the user gen- erated, and then associate them with the components on the sending page. e 2 This is how the default JSF implementation works. Some other implementations may use view identi- fiers differently; for example, the Smile [Smile] open source implementation allows you to map a view identifier to a particular Java class that creates a component tree, rather than a JSP page. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> 62 CHAPTER 2 JSF fundamentals This is the main job of the Restore View phase—to find the current view and apply the user’s input to it. In this case, it will look for the view in the user’s ses- sion. If the view isn’t available (the user has never been to this page before), the framework discards the current view (if there is one), and creates a new one based on the requested view identifier. Once the view has been created or retrieved, it is then stored in the current FacesContext. Listing 1.1 in chapter 1 shows the code for hello.jsp in our Hello, world! application. Let’s take a look at the component tree that represents this page (see figure 2.5).Figure 2.5 The tree of components generated by hello.jsp. Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es> The Request Processing Lifecycle 63 As you can see, the page is represented by a simple component tree. The view starts with a UIViewRoot component, which is the container for all of the other controls on the page. It has one child, an HtmlForm component with the identifier welcomeForm. This form has several children, including an HtmlInputText compo- nent called helloInput and two HtmlCommandButton components with the iden- tifiers redisplayCommand and goodbyeCommand. One of its children is an HtmlOutputLabel that has a child HtmlOutputText component as well. Restoring the view also ensures that the component’s values, as well as any event listeners, validators, or converters associated with components in the tree, are restored. In this case, the HtmlInputText component has a LongRange valida- tor associated with it, which is restored with the components in the view. In addition, redisplayCommand has an action property, and goodbyeCommand has an actionListener property, both of which are restored. If any of the components in the tree are bound to a backing bean property, this is where the bean’s property and the component instance are synchronized with each other. In this example, the controlPanel property of HelloBean would be synchronized with the HtmlPanelGrid component called controlPanel in the view. This allows the backing bean listener methods to manipulate the compo- nent in code when they’re handling events. This is also the phase where the language for the view is set, based on the val- ues of the HTTP request sent to the browser. If this request was a postback, JSF will now proceed to the next phase. However, if it is an initial request (the first time the user has requested this page), JSF will skip to the Render Response phase, because there is no user input to process. 2.2.2 Phase 2: Apply Request Values Each UI component that accepts input has a submitted value that represents the user’s original data from the user. During the Apply Request Values phase, the framework sets that submitted value based on the parameters sent in the request. This process is called decoding. In hello.jsp, each component was assigned a component identifier like this: <h:inputText id="helloInput" value="#{helloBean.numControls}" required="true"> ... </h:inputText> This declares an HelloInputText component with the component identifier helloInput. When JSF encodes this component as HTML, the identifier sent to the browser is composed of the component’s identifier prefixed by the identifier Licensed to JOSE CARLOS ROMERO FIGUEROA <jose.romero@galicia.seresco.es>
Docsity logo



Copyright © 2024 Ladybird Srl - Via Leonardo da Vinci 16, 10126, Torino, Italy - VAT 10816460017 - All rights reserved