P. 1
JSFSkript

JSFSkript

|Views: 128|Likes:
Publicado porMahendran Rethinam

More info:

Published by: Mahendran Rethinam on Apr 19, 2011
Direitos Autorais:Attribution Non-commercial

Availability:

Read on Scribd mobile: iPhone, iPad and Android.
download as PDF, TXT or read online from Scribd
See more
See less

09/18/2011

pdf

text

original

Sections

  • 1Introduction
  • 1.1 JSF in Comparison to other Web Frameworks
  • 1.1 The JSF Application Structure
  • 1.2 The JSF Concepts
  • 1.3 UIComponents
  • 1.4 Renderers
  • 1.5 Validators
  • 1.6 Backing Beans
  • 1.7 Converters
  • 1.8 Events and Event Listeners
  • 1.9 Navigation
  • 1.10 The JSF expression language
  • 2Easy Example: Hello World!
  • 2.1 Hello.jsp
  • 2.2 HelloBean.java
  • 2.3 faces-config.xml
  • 2.4 web.xml
  • 3JSF Application Configuration
  • 3.1 The Directory Structure
  • 3.2 The Deployment Descriptor
  • 3.3 The JSF Configuration File
  • 3.4 Configuration and Navigation Example
  • 3.5 Hello.jsp
  • 3.6 PersonDetails.jsp
  • 3.7 Goodbye.jsp
  • 3.8 faces-config.xml
  • 3.9 Navigation
  • 3.10 HelloBean.java
  • 4The Standard JSF Components
  • 4.1 The Layout of the Components
  • 4.2 The Output Components
  • 4.3 The Basic Input Components
  • 4.4 Choice Input Components
  • 4.5 Data Tables
  • 4.6 Processing Row-Specific Events
  • 4.7 The Command Components
  • 5Messaging
  • 5.1 Messages
  • 5.2 Overriding standard Messages
  • 5.3 Constructing Application Messages
  • 6Request Processing
  • 6.1 Restore View
  • 6.2 Apply Request Values
  • 6.3 Process Validation
  • 6.4 Update Model Values
  • 6.5 Invoke Application
  • 6.6 Render Response
  • 7Validators and Converters
  • 7.1 Standard Validators
  • 7.2 Validator Methods
  • 7.3 Validator Classes
  • 7.4 Automatic Conversion
  • 7.5 Standard Converters
  • 7.6 Using Custom Converters
  • 8Internationalization
  • 8.1 Load the Resource Bundle
  • 8.2 Configuring Locales
  • 8.3 Creating Resource Bundles
  • 8.4 Using Resource Bundles
  • 8.5 Constructing Localized Messages
  • 8.6 Using Localized Message Bundles for Application Messages
  • 9Custom Tags
  • 9.1 The different parts of a Custom Tag
  • 9.2 The Greater-Than Validator
  • 10.1 The Component Hierarchy
  • 10.2 Component Data Collections
  • 10.3 Value Holder
  • 10.4 Example of a Custom Component

Berner Fachhochschule

Software Schule Schweiz

JavaServer Faces
java.sun.com/javaee/javaserverfaces

Dr. Beatrice Amrhein

May 08

2

Table of Contents
1
1.1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 1.9 1.10

Introduction ...............................................................................................................................5
JSF in Comparison to other Web Frameworks....................................................................................................5 The JSF Application Structure..............................................................................................................................8 The JSF Concepts................................................................................................................................................9 UIComponents.....................................................................................................................................................9 Renderers...........................................................................................................................................................10 Validators...........................................................................................................................................................10 Backing Beans...................................................................................................................................................10 Converters..........................................................................................................................................................10 Events and Event Listeners................................................................................................................................10 Navigation..........................................................................................................................................................10 The JSF expression language............................................................................................................................11

2
2.1 2.2 2.3 2.4

Easy Example: Hello World! ..................................................................................................13
Hello.jsp..............................................................................................................................................................13 HelloBean.java...................................................................................................................................................15 faces-config.xml.................................................................................................................................................16 web.xml..............................................................................................................................................................16

3
3.1 3.2 3.3 3.4 3.5 3.6 3.7 3.8 3.9 3.10

JSF Application Configuration .............................................................................................17
The Directory Structure......................................................................................................................................17 The Deployment Descriptor................................................................................................................................17 The JSF Configuration File.................................................................................................................................18 Configuration and Navigation Example..............................................................................................................21 Hello.jsp..............................................................................................................................................................21 PersonDetails.jsp...............................................................................................................................................22 Goodbye.jsp.......................................................................................................................................................23 faces-config.xml.................................................................................................................................................23 Navigation..........................................................................................................................................................25 HelloBean.java...................................................................................................................................................26

4
4.1 4.2 4.3 4.4 4.5 4.6 4.7

The Standard JSF Components ............................................................................................27
The Layout of the Components..........................................................................................................................27 The Output Components....................................................................................................................................28 The Basic Input Components.............................................................................................................................28 Choice Input Components..................................................................................................................................29 Data Tables........................................................................................................................................................31 Processing Row-Specific Events........................................................................................................................32 The Command Components..............................................................................................................................34

5
5.1 5.2 5.3

Messaging ...............................................................................................................................35
Messages...........................................................................................................................................................35 Overriding standard Messages..........................................................................................................................36 Constructing Application Messages...................................................................................................................37

6
6.1 6.2 6.3 6.4 6.5 6.6

Request Processing ...............................................................................................................41
Restore View .....................................................................................................................................................41 Apply Request Values .......................................................................................................................................42 Process Validation..............................................................................................................................................42 Update Model Values ........................................................................................................................................42 Invoke Application .............................................................................................................................................42 Render Response..............................................................................................................................................42

7
7.1 7.2 7.3 7.4 7.5 7.6

Validators and Converters .....................................................................................................43
Standard Validators............................................................................................................................................43 Validator Methods..............................................................................................................................................44 Validator Classes...............................................................................................................................................44 Automatic Conversion........................................................................................................................................45 Standard Converters..........................................................................................................................................45 Using Custom Converters..................................................................................................................................46

3

...............................................................................................................................................................................................57 10 10...........4 JSF Custom Components ...................3 10..............................................51 9 9...........................................................................................................................................................................................................4 8....................6 Internationalization ........................................................49 Constructing Localized Messages .............................................................................................................................................................................................................................53 The Greater-Than Validator ....................................................................................63 4 ...................49 Using Localized Message Bundles for Application Messages ...........................................................................................2 10..................................5 8.........................................3 8................................62 Example of a Custom Component ...................................................8 8......48 Creating Resource Bundles........................................................47 Load the Resource Bundle..............................61 Component Data Collections...........................61 Value Holder..........1 8.........47 Configuring Locales..................53 The different parts of a Custom Tag.............................................................................................................................2 Custom Tags .......1 9....................1 10........................................................................................................2 8..........................................................................................................61 The Component Hierarchy........................................................................................................................48 Using Resource Bundles............................................................................

IBM WebSphere Application Developer. JSF defines a set of JSP tags that generate HTML form elements that can be bound to JavaBean properties. As a result. http://www.. Another distinct advantage of JavaServer Faces technology is that it has been designed to allow easy integration into tools. Because the JavaServer Faces technology architecture separates the definition of a component from its rendering. or more complex ones. error handling. In fact. the extensible component APIs of JavaServer Faces technology allow you to extend the standard set of components and create entirely new components.1 Introduction 1.org/). such as a WML client. and many third parties have already done so and have made their component libraries publicly available (e. For example. such as input fields. MyFaces. Oracle JDeveloper).g. a component used for selecting an item from a list can be rendered as a menu or a set of radio buttons. JavaServer Faces technology already has wide industry support and is build in several web application development IDEs (Sun Java Studio Creator. such as what to do when a user clicks a button or a hyper link. None of this is possible with Struts. which includes: • • • • A standard component API for a wide range of components. these components have no object representation on the server and they can only be rendered to an HTML client.. The greatest advantage that JSF technology has over Struts is its flexible. which also means that it has no event model for responding to component events and no facility for saving and restoring component state. extensible UI component model. you can render your components in different ways or even for different clients. . While Struts does have a useful tag library for rendering components on the page. 5 . Struts has no notion of server-side components. such as scrollable data tables.) Web Frameworks JSF Struts JSP Servlets Web server 3 HTTP request / response Like the Struts framework. Conversion and validation. Moreover. A separate rendering model that defines how to render the components in various ways. Developers can also create their own components based on the JSF APIs. An event model that defines how to handle events generated by activating a component.myfaces. including simple ones.1 JSF in Comparison to other Web Frameworks Automatic markup generation Declarative integration of backing beans UI component model Server side handling of UI events Type conversion Navigation Form handling and validation Extensible templating mechanism Integration with Java (session management.

JSF is also responsible for making sure that every UIComponent you have used on your pages is properly displayed on your browser.xml is the central configuration file for JSF applications. we define the navigation rules. JSF applications run on the server and can integrate with other subsystems like EJBs. 6 . JSF is responsible for translating that request into an event that can be processed by your application logic on the server (usually by the backing bean). it causes a request to be sent from your web browser to the server. When a user clicks a button in a JSF application. Here. faces-config.Web browsers don't know anything about JSF components or events. or more precisely to the FacesServlet. web services or databases. the used backing beans and so on.

1"> <jsp:directive.com/jsf/html" version="2.A simple JSF Page Here is an example of a simple page with a label („Your Name“) with an input text field and a submit button („Say Hello“).sun. all JSF tags can be used.name}"/> <h:outputText value="Your Age: "/> <h:commandButton value="Say Hello" action="#{helloBean. At runtime. a JSF page looks similar to a normal HTML or JSP page. 7 .page contentType="text/html"/> <html xmlns="http://www. world!</title> </head> <body> <f:view> <h:form> <h:outputText value="Your Name: "/> <h:inputText value="#{helloBean. As soon as we define the JavaServer tag namespaces (core and html). After translation.ViewState" value="j_id1:j_id2" /> <span id="main:o1">Your Name: </span> <input id="main:i1" type="text" /> <input id="main:submit" type="submit" value="Say Hello"/> </form></body> </html> The outputText is converted to normal text.faces.jsp" enctype="application/x-www-form-urlencoded"> <input type="hidden" name="main" value="main" /> <input type="hidden" id="javax.sun.0" encoding="UTF-8"?> <html><head><title>Hello.com/jsf/core" xmlns:h="http://java. Hidden input fields are used to transmit state information about the client or server. <jsp:root xmlns:jsp="http://java.com/JSP/Page" xmlns:f="http://java. world!</title></head> <body> <form id="main" name="main" method="post" action="/helloWorld1/faces/hello. These pages can also be designed by an IDE like Sun Java Studio Creator.org/1999/xhtml"> <head> <title>Hello.w3.sun. IBM WebSphere or Oracle JDeveloper. the inputText to a input tag and the submit button to a submit input tag. the generated HTML page looks as follows: <?xml version="1. the FacesServlet automatically translates these tags to a HTML form.sayHello}"/> </h:form> </f:view> </body> </html> </jsp:root> For the web page designer.

The Faces Servlet is provided by the JSF Application and is responsible for the communication between the server and the clients (Front Controller pattern). Client Server HTML Page HTTP Faces Servlet JSF View HTML Elements UI Components EL Backing Bean Model Object JSP Page Faces Config 8 . Define page navigation in the application configuration resource file In the JSP Page we use the the unified expression language (EL. The HTML Page (with HTML Elements) as well as all the JSF Views (with the necessary UI Components) are automatically generated form the JSP Page. cf. The configuration file contains the name of the corresponding backing bean. Add managed bean declarations to the application configuration file (Faces Config).10) to bind UI component values and objects to backing bean properties or to reference backing bean methods from UI component tags. Develop the Model Object (business logic) Develop the backing beans with the properties as well as the used action methods.1. Section 1.1 The JSF Application Structure Developing a simple JavaServer Faces application usually requires the following tasks: • • • • • Create the JSP Pages: The JSP Pages using html and core tags.

JSF applications communicate by events. On user input. This means. Unlike Swing. JSF UIComponents live on the server side. JSF provides all the standard components like labels. and you don't have to develop any complicated combinations of HTML. In JSF applications. Validators verify the value of a component and generate an error message (if necessary). Converters translate and format the components value and generate an error message (if necessary). UIComponents are built as JavaBeans. which are displayed by the dedicated renderer. methods. In general. In order to use a UIComponent. text fields.. CSS and JavaScript. they have properties.3 UIComponents Like Swing components.2 The JSF Concepts The following is a UML class diagram showing the different concepts of JSF.. model objects don't know anything about the user interface. such as the color or the default value. because the core functions are encapsulated within a reusable package. not on the client. list boxes. This enforces a MVC-style architecture. you just have to configure some properties.1. buttons. Event listeners consume events and can execute model objects. text fields. the backing beans are automatically updated. The outcome of an action method can be used to specify the next page to be shown (navigation).). hyper links. Backing beans contain event listeners and action methods. Providing these UI elements as components makes development much easier. 1. which perform the core application logic. 9 . The view object contains a tree of UIComponents (output labels. panels or data tables. . and support event handling. command buttons.

JSF ships with converters for common types like dates.4 Renderers Not all JSF components are responsible for their own rendering. they handle formatting and localization. You can attach one or more validators to any input component. Furthermore. 1. JSF uses JavaBeans to handle events with event listeners and handlers. 10 . 1. JSF allows separate classes to handle the rendering process. JSF provides a standard render kit for its UIComponents. 1. but anybody can develop additional converters which are applied internally during encoding and decoding. External validators are useful for generic cases. the renderer extracts the request parameters (decoding). JSF allows you to declaratively associate backing beans with UIComponents. data model events (select a row for processing) and phase events (at the beginning and at the end of each phase in the processing life cycle. boolean or numbers.6 Backing Beans In JSF applications the interaction between the model and the user interface is performed by backing beans.8 Events and Event Listeners In JSF applications there is no need of thinking in terms of HTTP requests and responses. They contain properties you want to retrieve from the user and provide event listener methods which can act on these properties and perform some application processing. action events (clicking on a button or link). Renderers create a visual representation for the client (encoding) and. 1. JSF supports the development of custom renderers as well. Whenever the value of the UIComponent changes. Any component may fire one or more events. These rules are defined in the JSF configuration file (faces-config.5 Validators Validators are used to examine the correctness of the given input values. such as whether a value is required or not. There are four standard events: value-change events (value change of a component). You can use a JSF EL expression to bind the value of a UIComponent with a specific backing bean property.1.7 Converters Converters translate an object to a string for display and from an input string to a Java object. Events capture the way the user interacts with UI components. Those classes are called renderers. JSF handles validation in three ways: • at the UIComponent level • via validator methods in backing beans • in validator classes UIComponents usually handle simple validation. However.xml). the associated backing bean property is automatically updated. see chapter 6). Like Swing. which means you register one or more event listeners with it. 1. The navigation handler is responsible for deciding which page to load depending on the outcome of an action method. when JSF receives a response form the user. Navigation rules define what outcomes are understood and which page to load on what outcome. Validator methods are useful when you need to validate one or more fields on a form (and you don't need this validator for other components).9 Navigation JSF provides an elegant navigation system.

el). Method Expressions: • #{myBean. • #{not empty myBean.name}" /> renders this input text component only if helloBean.name is not null. • #{myBean. if the (actual) value of myProperty is not equal to 20 and greater than 10.10 The JSF expression language The main point of JSF expressions is to allow you to reference JavaBean methods. They are evaluated at runtime. but you can use them for logical and mathematical statements as well. the empty string or an empty collection. EL expressions can also reference object methods. if the (actual) value of myProperty in myBean is greater than 10. <h:inputText value="#{helloBean.myMap['key']} returns the object stored under the key 'key' of the map myMap. • #{myBean. JSF 1. i.1. <h:commandButton value="Say Hello" action="#{helloBean. or to evaluate simple statements. Expressions with operators • #{myBean. Usage of EL expressions in tags: • <h:outputText value="#{helloBean. • #{myBean.myProperty > 10} returns true.myMethod} assigns the method myMethod of the bean myBean.2 depends on the unified EL API (javax.1.helloText}"/> associates the helloText property of the helloBean backing bean with the output text component. if myProperty is not null. • • 11 .myProperty > 10} returns true.name}" rendered="#{not empty helloBean.myList[2]} returns the second element of (the list or array) myList of myBean.e. JSF expressions are used to associate UIComponent properties with backing beans. • • • The EL uses the number sign (#) to mark the beginning of an expression. to read or update bean properties.2 uses the Unified Expression Language (EL).sayHello}"/> assigns the action method „sayHello“ of the helloBean backing bean to the command button. without writing any Java code.myProperty} returns true. EL expressions can be two way: they can retrieve a properties value or update it. Value Expressions: • #{myBean.myProperty} returns the value of myProperty of the object myBean.myProperty != 20 && myBean. it uses the same expression language as JSP 2. JSF 1.

12 .

sun.sun. <p> 23. </f:view> 31. <f:view> 14. value="#{helloBean.css" rel="stylesheet" type="text/css"/> 10.com/JSP/Page" 3. <h:outputText value="Your Name: "/> 19.2 Easy Example: Hello World! We start with an easy but complete example. styleClass="header"/> 17.com/jsf/core" 4. <body> 13. value="#{helloBean. <p> 18.helloText}" 16. </p> 22.page contentType="text/html"/> 6. <html xmlns="http://www.</jsp:root> 13 .jsp 1. <h:commandButton id="sayHello" value="Say Hello" 28. </html> 33.sun.sayHello}"/> 29. where we learn to know all the key pieces which belong to a JSF application. </head> 12. </h:form> 30.w3. <h:outputText value="#{helloBean. <head> 9. <h:inputText id="helloAge" 25. </body> 32. <jsp:root xmlns:jsp="http://java. <link href="styles.1"> 5. <?xml version="1.1 Hello. </p> 27.name}"/> 21. xmlns:h="http://java. <title>Hello. <jsp:directive.com/jsf/html" version="2. 7. xmlns:f="http://java. We start with the JSP page: 2.0" encoding="UTF-8"?> 2.org/1999/xhtml"> 8. <h:inputText id="helloInput" 20. <h:outputText value="Your Age: "/> 24. action="#{helloBean. world!</title> 11.age}"/> 26. <h:form id="main"> 15.

here "Say Hello". <f:converter> and so on). The action attribute references the action method that computes the new helloText.Lines 1 to 5: First. The value attribute #{helloBean.helloText} specifies an JSF Expression Language reference to the property helloText of the backing bean. JSF tags can use the usual CSS-styles of HTML. The outcome of the action method can be used to handle navigation. The value attribute #{helloBean. Usually the prefixes „f“ and „h“ are used for these namespaces. JSF automatically synchronizes the value of the outputText with the helloText property. We can have more than one HtmlForm on the same page. The jsp:directive is used to define the content type of the target HTML page. Line 13: The <f:view> tag must enclose all other JSF related tags. Line 14: The <h:form> tag represents an HtmlForm component. The value attribute defines the button label.name} references the property name of the backing bean. Line 27: The <h:commandButton> specifies an HtmlCommandButton component. which is a container for other components and is used for posting information back to the server. output labels and forms. Lines 19: <h:inputText> creates a new HtmlInputText component that accepts text input. <f:validator>. Lines 8-11: The header of the HTML page. whereas the core tags are independent of a particular render kit (like <f:view>. HtmlCommandButtons send action events to the application when they are clicked by a user. 14 . we declare the namespaces for the core JSF tag libraries. but all input controls must be nested within a <h:form> tag. The „h“ tag library elements usually render HTML elements. Line 15: The <h:outputText> tag creates an HtmlOutputText component. These provide custom tags like text boxes. which displays read-only text on the screen.

*/ private String name. } /** Get the hello text. */ private int age. */ public void setName(String name) { this.age = age. /** The age of the person. Its return value can be used to define the next page (navigation). */ public void setAge(int age) { this. } /** Get the person name. whenever the „Say Hello“ button is pressed. */ private String helloText = "Hello World!".name = name.java package helloWorld. It computes the new helloText. } // property method for hello text // property methods for age // property methods for name } /** Define the text to say hello. /** The hello text. } /** Set the person name. */ // action method for „Say Hello“ public String sayHello() { // button if(age < 11) helloText="Hello " + name + "!". */ public String getHelloText() { return helloText. */ public int getAge() { return age. */ public String getName() { return name. 15 . else helloText="Good Morning " + name + "!".2 HelloBean.2. } /** Set the age. /** Get the age. return "hello". } The sayHello() method is called. public class HelloBean { /** The name of the person.

com/xml/ns/javaee" xmlns:xsi="http://www.jsp</welcome-file> </welcome-file-list> <!-.xml <?xml version="1.com/xml/ns/javaee http://java.Faces Servlet : Front Controller --> <servlet> <servlet-name>FacesServlet</servlet-name> <servlet-class>javax.3 faces-config.0' encoding='UTF-8'?> <faces-config xmlns="http://java.4 web. Those are automatically instantiated.sun.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.name}).FacesServlet</servlet-class> </servlet> <!-.com/xml/ns/javaee" xmlns:xsi="http://www.jsp (e.com/xml/ns/javaee/web-app_2_5.0" encoding="UTF-8"?> <web-app version="2. Furthermore.w3. 16 . The name of the bean object is helloBean.xml).webapp.xsd" version="1.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.com/xml/ns/javaee/web-facesconfig_1_2.2.jsp pages are xml documents --> <jsp-config> <jsp-property-group> <url-pattern>*.xml file we declare all of the managed beans.HelloBean </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> </faces-config> In the faces-config. 2. Here the only managed bean is helloWorld.xml <?xml version='1.w3.Welcome File --> <welcome-file-list> <welcome-file>faces/hello.sun. This name is also used in the EL expressions in hello. which is the main servlet (front controller) of the application.sun. All JSF requests are mapped to the FacesServlet. JSF applications require that you specify the FacesServlet.sun.faces.sun.g. World!</display-name> <description>Welcome to JavaServer Faces</description> <!-.2"> <managed-bean> <description>The HelloBean.jsp</url-pattern> <is-xml>true</is-xml> </jsp-property-group> </jsp-config> </web-app> All J2EE web applications are configured by a deployment descriptor file (web. #{helloBean.xsd"> <display-name>Hello.sun.Faces Servlet Mapping --> <servlet-mapping> <servlet-name>FacesServlet</servlet-name> <url-pattern>/faces/*</url-pattern> </servlet-mapping> <!-. It is good practice to choose similar names for the bean class and its object.com/xml/ns/javaee http://java.5" xmlns="http://java.HelloBean.</description> <managed-bean-name>helloBean</managed-bean-name> <managed-bean-class>helloWorld.

3.jar.xml</param-value> </context-param> <!-.com/xml/ns/javaee/web-app_2_5. the required jar files for all JSF applications are jsf-api.1 The Directory Structure Because JSF applications are standard Java web applications.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.2 The Deployment Descriptor JSF applications require a servlet.3 JSF Application Configuration 3.sun.xml deployment descriptor file. <?xml version="1. For JSF applications.CONFIG_FILES</param-name> <param-value>/WEB-INF/faces-config.w3. jstl.faces. jsf-impl. For the reference implementation (we use for this course).FacesServlet configuration and mapping --> <servlet> <servlet-name>Name of the Front Controller for your JSF Application.5" xmlns="http://java. This servlet is configured in the web.jar and standard.webapp.FacesServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Name of the Front Controller (the same as above!)</servlet-name> <url-pattern>path/*</url-pattern> </servlet-mapping> <!-.sun.jsp</welcome-file> </welcome-file-list> 17 . which acts as a front controller for the entire application (FacesServlet).jar. usually FacesServlet</servlet-name> <servlet-class>javax. there are two additions: the faces-config.xml file (where all the JSF configuration is placed) and (if your web container doesn't already support JSF) the jar files of your JSF library.Welcome File --> <welcome-file-list> <welcome-file>path/firstPage.xsd"> <display-name>Display Name used by GUI Tools</display-name> <description>Description of the Web application </description> <!-.jar. all of the necessary files must be packed in a directory structure that can be deployed to the web container.0"?> <web-app version="2.Configuration of faces-config file(s) (comma separated) --> <context-param> <param-name>javax.faces.sun.com/xml/ns/javaee" xmlns:xsi="http://www.com/xml/ns/javaee http://java.

custom validators or converters). The faces-config elements The application element contains basic configuration information.jsp are xml docs --> <jsp-config> <jsp-property-group> <url-pattern>*. The second group of elements are used to define custom behaviour (e. Usually. Strings defined in this bundle can replace standard validation and conversion error messages (cf. but the servlet-class must be javax.all pages ending with .FacesServlet. Chapter 8).3 The JSF Configuration File The main configuration file for a JSF application is the faces-config. All top level elements (application. 3. 18 .webapp. .g. managed-bean.jsp</url-pattern> <is-xml>true</is-xml> </jsp-property-group> </jsp-config> </web-app> The value of servlet-name is arbitrary. that every request to a resource of the form http://myURL/pattern is handled by the JSF servlet. to declare the backing beans and for the navigation configuration. The third group of elements is used to define advanced features like the registration of phase listeners. All elements of the configuration file must be enclosed within a <faces-config> element. such as the supported locales and message resource bundle. The first group of elements are used for general application configuration.. The faces servlet will then handle the request with the corresponding JSP page..<!-. The other elements are used for advanced programming.. The servlet-mapping makes sure.faces. factory) are optional and can be included once or more than once.xml file. you only need the first three configuration elements.

which will be created and initialized by the Managed Bean Creation Facility the first time it is requested by a JSF EL expression.. The life cycle element allows you to register one or more phase listeners. <description>. custom validators and custom converters (cf. The managed-bean element has a subelement named managed-property which can be used to initialize any read/write properties (Setter Injection pattern). Chapter 6).The component. <icon>. <display-name>. The managed-bean element is used to configure a managed bean. validator and converter elements are used to declare custom components. The following figure shows the full hierarchy of the managed bean element. render-kit. custom renderers.. Chapter 7). . 19 . Every managed bean must be declared in a separate entry. are optional elements. which are executed before or after each phase of the Request Processing Life cycle (cf. The factory element provides a mechanism to define custom Factories like a custom Application.or FacesContextFactory. generally used for tools.

<display-name> and <icon> elements are optional and are generally used for tools. For an example of a bean reference confer to the faces-config. . 20 . The same result is achieved by omitting the <from-view-id> element. a navigation-rule defines what outcomes are understood.xml of the next chapter. and we must have some way to move between them.The managed property element can even be used to assign a reference to a previously defined managed bean. and what pages to load based on those outcomes. For any given page. which means that the outcome may be produced by an arbitrary action method or even be a constant value. which means that this rule applies to all pages. . You must be careful about the scope of these objects. Each specific mapping between an outcome and a page is a navigation-case. The fromPage value can also be an asterisk ( * ). <navigation-rule> <description>description of navigation cases</description> <from-view-id>fromPage</from-view-id> <navigation-case> <from-action>action</from-action> <from-outcome>a return value of the action</from-outcome> <to-view-id>toPage</to-view-id> </navigation-case> <navigation-case> <from-action>action</from-action> <from-outcome>other return value of the action</from-outcome> <to-view-id>toPage</to-view-id> </navigation-case> . <description>. Web applications usually have multiple pages. because a managed bean can’t reference an object with a shorter life span than the managed bean itself. (other navigation cases for this page) </navigation-rule> The from-action element can be left out. The next chapter shows a full example of a managed bean with initial values for (some of) its properties and different navigation rules.

com/jsf/core" xmlns:h="http://java. 3.page contentType="text/html"/> <html xmlns="http://www.age}"/> </h:panelGrid> </p> <h:commandButton value="Say Hello" action="#{helloBean. the outputText fields for name and age get their values from the personDetails backing bean.w3.jsp page obtains two more buttons (Details / Goodbye). the user loads the persons detail page.com/jsf/html" version="2.sun.sayGoodbye}"/> </h:form> </f:view> </body> </html> </jsp:root> When we load the hello.3. By pressing the Details button.sun.sayHello}"/> <h:commandButton value="Details" action="details"/> <h:commandButton value="Goodbye" action="#{helloBean.jsp page for the first time.jsp <jsp:root xmlns:jsp="http://java.name}"/> <h:outputText value="Your Age:"/> <h:outputText id="helloAge" value="#{personDetails. The default values for name and age in the backing bean are set by the Managed Bean Creation facility (managed-property in the faces configuration file) at creation time (cf. world!</title> </head> <body> <f:view> <h:form> <h:outputText value="#{helloBean.helloText}" styleClass="header"/> <p> <h:panelGrid columns="2" cellpadding="3"> <h:outputText value="Your Name:"/> <h:outputText value="#{personDetails.5 Hello.xml below). 21 .org/1999/xhtml"> <head> <link href="styles.sun.css" rel="stylesheet" type="text/css"/> <title>Hello.com/JSP/Page" xmlns:f="http://java. faces-config. The hello. the Goodbye button leads to the goodbye page.1"> <jsp:directive.4 Configuration and Navigation Example We extend our first easy example by introducing two new features: navigation rules and managed properties.

name}"/> <h:outputText value="Your Age:"/> <h:inputText id="helloAge" value="#{personDetails.6 PersonDetails.com/jsf/core" xmlns:h="http://java. The back button leads back to the hello page.1"> <jsp:directive.jsp The PersonDetails page can be used to change the properties for name.sun. <?xml version="1.favoriteNumbers[1]}" size="4"/> <h:inputText value="#{personDetails.age}" size="4"/> </h:panelGrid> </p> <p> <h:outputText value="Enter your favorite Numbers:"/> <h:panelGrid columns="3" cellpadding="3"> <h:inputText value="#{personDetails.org/1999/xhtml"> <head> <link href="styles.css" rel="stylesheet" type="text/css"/> <title>Person Details</title> </head> <body> <f:view> <h:form> <h:outputText value="Person Details" styleClass="header"/> <p> <h:panelGrid columns="2" cellpadding="3"> <h:outputText value="Your Name:"/> <h:inputText value="#{personDetails.page contentType="text/html"/> <html xmlns="http://www. age and the favorite numbers of the given person.sun.favoriteNumbers[0]}" size="4"/> <h:inputText value="#{personDetails.favoriteNumbers[2]}" size="4"/> </h:panelGrid> </p> <h:commandButton value="Back" action="back"/> </h:form> </f:view> </body> </html> </jsp:root> The panelGrid components above is used to align the two input text fields for name and age. The favorite numbers are saved in an array or vector of integers in the person details backing bean.3.0" encoding="UTF-8"?> <jsp:root xmlns:jsp="http://java. All of these properties read their initial value at creation time from the faces-config.w3.com/jsf/html" version="2.xml file. 22 .sun.com/JSP/Page" xmlns:f="http://java.

1"> <jsp:directive. <?xml version='1. The corresponding setFavoriteNumbers method takes a Vector or a List of values as input argument. world! </title> </head> <body> <f:view> <h:form> <h:outputText value="#{helloBean. The properties are initialized with <managed-property> elements. This instance can be referenced with the expression #{personDetails} (or #{sessionScope.PersonDetails and and store it in the session under the name personDetails the first time the bean is accessed.sun.jsp page doesn't need a backing bean for its own. The <value> element contains the default value of the property specified in the <property-name> element.w3. as it only prints out the goodbye helloText. favoriteNumbers is a vector of (three) numbers.helloText}" styleClass="header"/> </h:form> </f:view> </body> </html> </jsp:root> 3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun. Setter Injection pattern).sun.xsd" version="1.2"> 23 .com/xml/ns/javaee" xmlns:xsi="http://www.7 Goodbye.sun.com/jsf/html" version="2. the same instance of personDetails will be used.page contentType="text/html"/> <html xmlns="http://www.sun.sun.3.css" rel="stylesheet" type="text/css"/> <title>Hello.com/xml/ns/javaee http://java.com/JSP/Page" xmlns:f="http://java.helloBean backing bean.com/jsf/core" xmlns:h="http://java.org/1999/xhtml"> <head> <link href="styles.0' encoding='UTF-8'?> <faces-config xmlns="http://java.xml The Managed Bean Creation Facility uses the <managed-bean> element to create an instance of helloWorld. As long as the same session is in use.0" encoding="UTF-8"?> <jsp:root xmlns:jsp="http://java. <?xml version="1. The vector is initialized by the <list-entries> element and its three <values> children.jsp The goodbye.8 faces-config. The Bean Creation facility uses the associated setter method to assign the initial values to the right properties (Property Injection: cf.personDetails }).com/xml/ns/javaee/web-facesconfig_1_2.w3. The same holds for the helloWorld.

the helloBean backing bean needs a reference to the personDetails backing bean. The reference to the previously defined managed bean (PersonDatails) can be assigned to the helloBean via a normal JSF EL expression (Dependency Injection).<managed-bean> <description>Detail Information of a person</description> <managed-bean-name>personDetails</managed-bean-name> <managed-bean-class>helloWorld.util.Vector</property-class> <list-entries> <value-class>java.lang.Integer</value-class> <value>3</value> <value>17</value> <value>347</value> </list-entries> </managed-property> </managed-bean> <managed-bean> <managed-bean-name>helloBean</managed-bean-name> <managed-bean-class>helloWorld.HelloBean </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>personDetails</property-name> <value>#{personDetails}</value> </managed-property> <managed-property> <property-name>helloText</property-name> <value>Hello World!</value> </managed-property> </managed-bean> To print out the name and the age of the given person.PersonDetails</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>name</property-name> <value>John</value> </managed-property> <managed-property> <property-name>age</property-name> <value>17</value> </managed-property> <managed-property> <property-name>favoriteNumbers</property-name> <property-class>java. 24 .

3.sayGoodbye}</from-action> <from-outcome>goodbye</from-outcome> <to-view-id>/goodbye. • From the personDetails page we can go back to the hello.sayHello}</from-action> <from-outcome>hello</from-outcome> <to-view-id>/hello.jsp page will be reloaded (with the new values entered by the user).navigation rules --> <navigation-rule> <description>Navigation from the hello page.jsp</from-view-id> <navigation-case> <from-action>#{helloBean.jsp page by pressing the „Back“ button.</description> <from-view-id>/details.jsp page: • By pressing the „Say Hello“ button.jsp</from-view-id> <navigation-case> <from-outcome>back</from-outcome> <to-view-id>/hello. <!-.jsp and one for the personDetails.jsp page.jsp</to-view-id> </navigation-case> </navigation-rule> <navigation-rule> <description>Navigation from the Person Details page.9 Navigation In the faces configuration file. • Pressing the „Details“ button leads us to the personDetails. we find three navigation cases for hello.</description> <from-view-id>/hello. Therefore the hello. which leads us to the goodbye.jsp</to-view-id> </navigation-case> <navigation-case> <from-action>#{helloBean. • Pressing the „Goodbye“ button executes the sayGoodbye action method which produces the outcome „goodbye“. the sayHello action is processed which produces the outcome „hello“.jsp</to-view-id> </navigation-case> </navigation-rule> </faces-config> 25 .jsp</to-view-id> </navigation-case> <navigation-case> <from-outcome>details</from-outcome> <to-view-id>/details.jsp page.

java The helloBean.getName() + "!". */ public void setPersonDetails(PersonDetails personDetails) { this. else helloText = "Goodbye " + personDetails. } /** Set the hello text.getName() + "!". else helloText = "Good Morning " + personDetails. } /** Get the hello text. } /** Define the text to say goodbye.3. return "hello". /** The hello text. */ private String helloText. /** Set the person details reference.java file has a new action method for the Goodbye button: sayGoodbye(): package helloWorld.getName() + "!". } } 26 . */ public String getHelloText() { return helloText. } /** Define the text to say hello. */ public String sayGoodbye() { if (personDetails.getName() + "!". public class HelloBean { /** The reference to the person deatils backing bean */ private PersonDetails personDetails. " + personDetails. return "goodbye".personDetails = personDetails.10 HelloBean.getAge() < 11) helloText = "Hello " + personDetails. */ public void setHelloText(String text) { helloText = text.getAge() < 11) helloText = "See you. */ public String sayHello() { if (personDetails.

4 The Standard JSF Components In this chapter. the first two components form the first row (one per column). <h:panelGrid columns="2" headerClass="page-header" cellpadding="1" border="1" width="40%"> <f:facet name="header"> <h:outputText value="This is the table header"/> </f:facet> <h:outputText value="(1. if set to false suppresses rendering of this component • value: The components value.1.1)"/> <h:outputText value="(1. We start with the basic attributes. The width. typically a value binding • required: A boolean value. border. <h:panelGrid columns="2" headerClass="page-header" cellpadding="1" border="1" width="40%"> <h:outputText value="(1. and cellpadding properties are passed through to the HTML table.1)"/> <h:panelGroup> <h:outputText value="(1. They provide the basic set of functionality necessary for building HTML-based web applications. Child components are organized according to the specified number of columns.2)"/> </h:panelGrid> The HtmlPanelGroup component groups a set of components together.1)"/> <h:outputText value="(2. You can expect third-party developers to provide additional components as well. • id: An identifier for a component • rendered: A boolean value.2)"/> <h:outputText value="(2. if true a value is required for this input field • styleClass The CSS class name which should be used for this component 4. When we specify two columns.2. Unlike the HTML table. so that they can be treated as a single entity.2.2. you don’t have to explicitly denote columns and rows. static component layouts (it maps to the <table> element). Here we will focus on the most important components only.2)"/> </h:panelGrid> 27 . and so on. the next two form the second row. respectively.2)"/> </h:panelGroup> <h:panelGroup> <h:outputText value="(2.1)"/> <h:outputText value="(1.1 The Layout of the Components HtmlPanelGrid is useful for creating arbitrary. You can also configure header and footer with facets that map to the <thead> and <tfoot> table subelements.1)"/> <h:outputText value="(2.1)"/> </h:panelGroup> <h:outputText value="(2. which are applicable to most of the components. we cover the standard components that all JSF implementations must support.

3 The Basic Input Components The HtmlInputText component is used for basic user input. This allows target devices to define shortcuts for input elements. HtmlInputText is the most common input control. <h:inputText id="helloInput" value="#{helloBean.. The most basic output component is HtmlOutputText (<h:outputText>).helloText}" styleClass="header"/> <h:outputText value="#{helloBean.2 The Output Components The purpose of the output components is to display data.helloText}" rows="5" /> 28 . you can use the HtmlInputTextarea component. <h:inputTextarea value="#{helloBean.goodbyeText}" styleClass="header"/> The HtmlOutputLabel component is used for associating labels with form elements (InputText.age}" size="4" disabled="true"/> The size and disabled properties are passed through to the HTML input tag. In this example.name}" required="true" accesskey="N"/> </h:panelGroup> 4..name}" size="30" required="true"/> <h:inputText id="helloAge" value="#{helloBean. Example: <h:outputText value="#{helloBean. the component is associated via a value-binding expression with the name property of helloBean. HtmlOutputLabel is translated to the HTML <label> element.4. . ChoiceButton. You can specify literally the data that they display or have them display properties from backing beans. but it is restricted to a single line. It maps to a simple text field—the <input> element with type “text”. HtmlOutputText converts the given value to a string and displays it with optional CSS style support.). If you need a multi line input field. Example <h:panelGroup> <h:outputLabel for="helloInput" accesskey="N"> <h:outputText value="Your Name:"/> </h:outputLabel> <h:inputText id="helloInput" value="#{helloBean.

you preferably use a HtmlSelectManyCheckbox (see next chapter). 4. a description. and itemValue properties or a value-binding expression. In JSF.password}" size="10" maxlength="10"/> For the input of boolean values. The number of items displayed is always one. 29 . itemLabel. Components in the SelectMany and SelectOne families.The HtmlInputSecret component is used to display a password input field. a selection item represents a single choice.animal[3]}"/> Alternatively. for components like HtmlSelectManyCheckbox.g. <h:inputSecret value="#{user. like HtmlSelectManyCheckbox and HtmlSelectOneListbox. only one of these components is described here: HtmlSelectOneMenu. Therefore. <h:outputLabel for="accepted" accesskey="A"> <h:outputText value="Accepted"/> </h:outputLabel> <h:selectBooleanCheckbox value="#{helloBean. we can use a HtmlSelectBooleanCheckbox component.accepted}" id="accepted"/> The selectBooleanCheckbox component works fine for a single check box on a form. display lists of items. and a label. and has a value.animalList}"/> These selectItem(s) tag can be used to configure another component’s selection list (e. If you want to associate multiple check boxes with a single property.4 Choice Input Components User interfaces often allow a user to select one or more items from a set of possible choices. A UISelectItem component are used to display items in a list and to select one or more items from this list. you can use a selectItems tag with a value binding to a list or array of elements. <f:selectItem itemValue="0" itemLabel="cats"/> <f:selectItem value="#{myBean. All of these choice components work in a similar way. HtmlSelectOneRadio. so the result is a combo box (also called a drop-down list box). Any text the user types is displayed using the asterisk or some other character (depending on the browser). HtmlSelectOneMenu displays its child items in a list box using the HTML <select> element. <f:selectItems value="#{myBean. You can either use the value itemDescription. HtmlSelectOneListbox or HtmlSelectOneMenu).

animal}" accesskey="A"> <f:selectItems value="#{helloBean. } public void setAnimals(List<String> items) { animals = new ArrayList<SelectItem>(). public String getAnimal() { return animal.HelloBean </managed-bean-class> <managed-bean-scope>session</managed-bean-scope> <managed-property> <property-name>animals</property-name> <list-entries> <value>Cat</value> <value>Dog</value> <value>Bird</value> </list-entries> </managed-property> </managed-bean> In the backing bean. you have to provide the corresponding get and set methods for the favorite animal and the selection list of animals: private String animal. you have to provide an array or a list property named animals. for (String item : items) animals. } 30 .<h:outputText value="Your Favorite Animal "/> <h:selectOneMenu id="animal" value="#{helloBean.add(new SelectItem(item)).xml): <managed-bean> <description>The one and only HelloBean.animal = a. which can either be initialized in the backing bean (e.g. } public void setAnimal(String a) { this. } public List<SelectItem> getAnimals() { return animals. private List<SelectItem> animals. as list of strings) or in the faces configuration file.animals}"/> </h:selectOneMenu> In the corresponding JavaBean.</description> <managed-bean-name>helloBean</managed-bean-name> <managed-bean-class>helloWorld. Initialization in the faces configuration file (faces-config.

this. } 31 . 33). public Person[] getFriends(){ return friends.age}"/> </h:column> </h:dataTable> In the backing bean. 22)}. it displays that many rows (starting with the first). String lastName. a lastName and an age attribute. "Muster". HtmlDataTable uses the column components as a template for each column.firstName}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="Age"/> </f:facet> <h:inputText value="#{person.5 Data Tables The HtmlDataTable component displays an HTML <table>. The var property defines the name of the iterator variable (here person). If the facet tag has a name=“header“ attribute. For each row. } The Person class provides the corresponding entries: public class Person { String firstName.age = age. <h:dataTable value="#{helloBean. private Person[] friends = { new Person("Hans". The columns are specified with column components. int age. this. String lastName.lastName = lastName.firstName = firstName. "Meier".4. "Schmid". If the row property is specified. it is translated to a <thead> (table header) HTML tag.friends}" var="person" first="0" rows="2"> <h:column> <f:facet name="header"> <h:outputText value="Last Name"/> </f:facet> <h:inputText value="#{person.lastName}"/> </h:column> <h:column> <f:facet name="header"> <h:outputText value="First Name"/> </f:facet> <h:inputText value="#{person. new Person("Heidi". you have to provide a corresponding list of friends (here Person) with a firstName. int age){ this. 44). Person(String firstName. new Person("Peter".

. However. The LastName column uses an <h:commandLink> component instead of an outputText and the value of the <h:dataTable> is now an instance of javax.faces. DataModel has two subclasses: ListDataModel and ArrayDataModel. } public void setFirstName(String firstName){ this.public String getFirstName(){ return firstName.lastName}"/> </h:commandLink> </h:column> <h:column> <f:facet name="header"> <h:outputText value="First Name"/> </f:facet> . </h:column> </h:dataTable> The table looks similar to the previous one. In the JSF table we have to change the following entries: <h:dataTable value="#{personHandler. but there are some important differences. JSF offers a much easier way to represent tabular data through the abstract DataModel class. How can we determine which row of the table has been selected when handling the action event? You could find it out by using a query string parameter or a hidden field. These are convenience implementations of the abstract DataModel class with the following properties: 32 . .DataModel instead of the previous array of Person.firstName = firstName. .select}" immediate="true"> <h:outputText value="#{person. . we must figure out which table row the user selected to make the corresponding details available for display. } 4. To implement this feature.personModel}" var="person" border="1" cellspacing="0" rows="2"> <h:column> <f:facet name="header"> <h:outputText value="Last Name"/> </f:facet> <h:commandLink action="#{personHandler. } public String getLastName(){ return lastName.6 Processing Row-Specific Events A very common application feature is to have a table with summery information where each row is linked to the details about the item in that row. } .model.

helloBean = helloBean. The <h:dataTable> uses the personModel DataModel to read the table entries from.• • • • • boolean: rowAvailable is true.faces. if no row is selected) Object: wrappedData is the object representing the table. public DataModel getPersonModel() { personModel. public class PersonHandler { private DataModel personModel = new ArrayDataModel(). } public Person[] getPersons() { return helloBean. package helloWorld. false otherwise. int: rowCount is the number of rows (or -1 if unknown) Object: rowData the object at rowIndex (or null if rowIndex = -1) int: rowIndex gives the currently selected row (or -1. There are no changes necessary in the HelloBean or Person class. it populates the ArrayDataModel with the Person array returned by getPersons(). Other sublasses of DataModel are ListDataModel (for Lists) or ResultSetDataModel (for a JDBC ResultSet).model. return personModel. All we need is a new PersonHandler class as a wrapper for the array of Person objects.ArrayDataModel class which is a subclass of DataModel. } public void setHelloBean(HelloBean helloBean) { this. The <h:commandLink> in each table row is bound to the PersonHandlers select() method.setWrappedData(getPersons()). private Person selectedPerson. 33 . return "success".getRowData(). } } The getPersonModel() method creates an instance of the javax. } public String select() { selectedPerson = (Person) personModel. Therefore. The renderer together with the UIData component ensure that the DataModels rowIndex is positioned to the selected row when the action method is invoked. private HelloBean helloBean. Then. when the rowIndex property holds the index of an existing row. we can use getRowData() in the select() method to read the data of the selected person. import javax.faces.model.getFriends(). } public Person getSelectedPerson() { return selectedPerson.*.

else helloText = "Good Morning " + name + "!". <h:commandButton value="Say Hello" action="#{helloBean.sayHello}"/> <h:commandButton value="Goodbye" action="#{helloBean. The two standard command components are HtmlCommandButton (for displaying a button) and HtmlCommandLink (for displaying a hyper link).4.sayGoodbye}"/> The corresponding action Methods are defined in the backing bean: public String sayHello() { if (age < 11) helloText = "Hello " + name + "!". return "hello". Because they perform the same operation.7 The Command Components The command components represent an action initiated by the user. } 34 . their usage is quite similar.

the error is placed next to the component (so the user knows where the problem arises).. <h:message for="helloInput" showDetail="true" showSummary="true" errorStyle="color: red"/> The attributes showDetail and showSummary are optional. but that’s not a requirement. Example: Message for input control helloInput. converters. You can insert an fatalClass or a fatalStyle attribute to define a CSS class / CSS style for messages with fatal severity. Example: all messages for this page: <h:messages showDetail="true" showSummary="true" layout="table" errorStyle="color: red"/> 35 . You can insert an infoClass or an infoStyle attribute to define a CSS class / CSS style for messages with Info severity.1 Messages Multiple parts of a JSF application (validators. The default value for showDetail is true. Whenever possible. that for showSummary is false.Indicates that an error may have occurred. HtmlMessage is designed to display a message for a specific UI component.5 Messaging 5.. If you need to display multiple messages for a page.Represents an informational text to be send back to the user. It is typically used with input controls. or if a validator has problems with conversion). you should use HtmlMessages instead. HtmlMessage displays only the first one. • Error .You can insert a warnClass or a warnStyle attribute to define a CSS class / CSS style for messages with Warn severity. • Info . • Warn . ) can generate messages. Usually. application exceptions .Indicates an error like validation or conversion error. You can insert an errorClass or an errorStyle attribute to define a CSS class / CSS style for messages with error severity. Messages contain a summary and a detail text. Every message has a severity level which is equal to one of the following values. • Fatal .Indicates a serious (application) error. and is useful whenever you need to inform the user of any errors. these messages have to be displayed to the user. If more than one message is registered for a component (which can happen if more than one validator is registered.

<h:inputText id="helloInput" value="#{helloBean. these default messages are not very user friendly. In general.UIInput. javax.name}" required="true" requiredMessage="Please enter your name into this input field"> Furthermore.properties file then might look as follows: javax.INTEGER=The given input value '{0}' is not an integer. which is configured in the faces-config.faces.INTEGER_detail=The input value should be an integer like 17. messages.REQUIRED={0}: Validation Error: Value is required.properties).component.UIInput. These are configured using a normal Java message bundle.2_MR1/docs/api/index.sun. as long as you use the correct keys (see java.html for the list of message keys).com/javaee/javaserverfaces/ 1.converter.REQUIRED=Input value for {0} is required.component. .IntegerConverter. it will look for them in the JSP page and in the custom messages bundle (messages. javax.g.2 Overriding standard Messages All of the standard validators and converters have default messages.UIInput.properties file at /WEB-INF/classes --> <message-bundle>messages</message-bundle> </application> . </faces-config> Once. One possibility is to define an error message in the tag of the corresponding input component. you have defined a message bundle. Only if there is no user defined message. validator or converter looks for an error message.properties). you can selectively override the standard messages. We can override the default messages by a custom message bundle. – converterMessage for conversion errors and – validatorMessage for validation errors.component.xml file: <faces-config> <application> <!-. the details message texts are often missing. In the reference implementation.faces.converter. .component. javax.faces.messages. javax. Whenever a JSF component. it will take the predefined standard message. The used parameters are defined in the JSF documentation for the corresponding messages. The messages. we would find the following key/value pair.IntegerConverter.REQUIRED_detail=Input value for {0} must not be void.UIInput. Therefore we often would like to override these texts with custom messages. creating a message for an empty input field with a required=“true“ attribute: javax. for example.CONVERSION={0}: Conversion error occurred.faces. 36 . Possible values are – requiredMessage for required input.faces. Each JSF application can be associated with a single message bundle (e.faces.5.

Creating a Faces Message in the Backing Bean In the following action method we create a FacesMessage to inform the users about errors in the name input field. system or connection errors). context.message)). } You have to add this messages to the FacesContext.5. The addMessage function takes two parameters: the message id (either the component id or null. */ public String sayHello() { if (!isValidName(name)) { // create faces message FacesMessage message = new FacesMessage(FacesMessage. /** test whether given string is a valid name. you can create a message in your backing bean (or validator or converter class or method). The FacesMessage constructor takes the arguments severity. If we want to retrieve the application messages only (the messages. the summary string and the detail string. which belong to no component) we use the globalOnly attribute: <h:messages globalOnly=“true“>. helloText = "Hello!". if the message does not belong to any component) and the FacesMessage. For this.g. "Name is not valid!". } return "hello". from where the JSP page will read it afterwards: context. you want to inform the users about this. } else { // name is valid if (age < 10) helloText = "Hello " + name + "!".3 Constructing Application Messages Whenever one of your backing beans throws an exception or when an error occurs in your application logic (e. Application messages do not belong to any component on the jsp page. else helloText = "Good Morning " + name + "!". /** Define the text to say hello.length() > 0 && name.SEVERITY_ERROR. "Your name must not be empty and not start with // add message to faces context FacesContext context = FacesContext.getCurrentInstance().addMessage(null.charAt(0) == 'A').addMessage(null. } letter 'A'"). message). */ private boolean isValidName(String s) { return (name. 37 .

format(summary. we used hard coded message texts from our backing beans. instead.. you create a message (of type FacesMessage) by first extracting the name of the message bundle and from this the summary and detail string of the desired message. String detail = null.getString(key + "_detail").getMessageBundle(). } catch (MissingResourceException e) {} return new FacesMessage(severity.format(detail.Severity severity.getCurrentInstance(). // ( 2 ) try { summary = bundle. String name = context. params). summary. The following MessageFactory provides us with the desired FacesMessage: public class MessageFactory { public static FacesMessage getMessage(FacesMessage. detail). In your backing bean.getString(key).FACES_MESSAGES. params) { String summary = "?? key " + key + " not found ??".Retrieving Message Texts from the Message Bundle In the previous example. Object. // ( 3 ) detail = MessageFormat. In the following example we take this improved approach. FacesContext context = FacesContext. // ( 1 ) if (name == null) name = FacesMessage. // ( 3 ) summary = MessageFormat. you preferably use the custom message bundle to define your application messages and read these message texts from there. Therefore.getApplication(). params). you want to read those messages from a message bundle. ResourceBundle bundle = ResourceBundle. String key. detail = bundle.getBundle(name). Usually. // ( 4 ) } } 38 ..

*/ public String sayHello() { FacesContext context = FacesContext.charAt(0) == 'A'). helloText = "Hello!".SEVERITY_ERROR.converter.faces.Example: Print out an information message for invalid name values (cf. */ private boolean isValidName(String s) { return (name.IntegerConverter. javax. else helloText = "Good Morning " + name + "!".nameMessage".jsp <h:form id="main"> <h:outputText value="#{helloBean.component. javax.UIInput. MessageFactory. } /** test whether given string is a valid name.getCurrentInstance().properties file for the application message contains messages of the form: javax.INTEGER_detail={2}: The input value should be an integer like 17.REQUIRED_detail={0}: Input value must not be void.INTEGER=The given input value ''{0}'' is not an integer. helloBean.getMessage( FacesMessage. helloWorld. javax.helloText}" styleClass="header"/> <h:panelGrid columns="3"> <h:outputText value="Your Name"/> <h:inputText id="name" label="Name" value="#{helloBean. } The messages. name)). } else { if (age < 10) helloText = "Hello " + name + "!".UIInput. if (!isValidName(name)) { // create hello message and add it to faces context context.name}" required="true" requiredMessage="Please enter your name"/> <h:message for="name" errorClass="errorStyle" showDetail="false" showSummary="true"/> 39 . "helloWorld.converter. HelloWorld4).addMessage(null.faces.component.nameMessage= Name ''{0}'' is not valid! hello.faces.length() > 0 && name.java /** Define the text to say hello.IntegerConverter.REQUIRED= This value is required.faces. } return "hello".

country}" required="true"/> <h:message for="country" errorClass="errorStyle" showDetail="false" showSummary="true"/> </h:panelGrid> <h:commandButton value="Hello" action="#{helloBean.<h:outputText value="Your Age"/> <h:inputText id="age" label="Age" value="#{helloBean.age}" required="true"/> <h:message for="age" errorClass="errorStyle" showDetail="false" showSummary="true"/> <h:outputText value="Country"/> <h:inputText id="country" label="Country" value="#{helloBean.sayHello}"/> <h:commandButton value="Goodbye" action="#{helloBean.sayGoodbye}"/> <p> <h:messages layout="table" showDetail="true" showSummary="false" infoClass="infoStyle" errorClass="errorStyle" globalOnly="false"/> </p> </h:form> We then obtain either one or more error messages (in case of any input errors): or the application message created by the MessageFactory: 40 .

validators and converters If there is no (new) user input.6 Request Processing When a JSF view is requested. create them if necessary Restore or create the component values. event listeners. 6. the components in the view are asked to perform tasks in a certain order. defined as phases of a request processing life cycle.1 • • • • Restore View Extract the view ID and find current view Look up the components for the current view. The following graphic shows the main tasks for each phase. skip to render response phase (6) 41 .

3 • • • • Process Validation Convert submitted values: Convert the value of the submittedValue attribute of the component from string type to object. which update the backing bean with the (new) validated and converted local values of the components. If the local value has changed. Display the next view with the new values from the backing beans. Execute default action listener method. If there is a command button or a hyper link with an immediate property set to true. Call the event handler methods of all registered event listeners. If the conversion or the validation process throws an exception. Invoke the converters (object to string). validation takes place in this phase instead of the process validation phase. Choose the next page based on the action method's outcome. session. The set methods of these properties are called. This can be used for example for Cancel buttons. 6. because it prevents the validation of any input fields.6.6 • • • Render Response Save the state of the new view for later use in the restore view phase (1). If the immediate attribute of a component is set to true. a valueChangeEvent is fired and consumed by the registered listeners. application).5 • • • • Invoke Application Handle all fired events. the corresponding actions will be fired in this phase instead of the invoke application phase.4 • • Update Model Values Evaluate the JSF EL expressions in the components' value attribute to find the associated backing beans and properties (depending on the beans' scope: request. 6. the value is validated and set as the local value of this component.2 • • • • Apply Request Values Decoding: extract all user input from the input fields (and save them in the submittedValue attribute of the component). 6. 42 . 6. Create action events and add them to the faces context for later processing. the control will skip to the render response phase (6). Validate submitted values: After conversion.

When users see an object on the screen.1 Standard Validators JSF includes a few standard validators for the most common validation problems: <f:validateLength> can be used to ensure that the number of letters given in the input field is greater/smaller than or equal to the specified minimum/maximum value. <h:inputText id="helloAge" value="#{helloBean. Two Date objects can be compared and we can compute the elapsed time between the two dates. A Java Date object. and the associated object is not modified. they see it in terms of recognizable text. The associated object in the backing bean is updated only if the value is accepted. like May 23. JSF provides a set of standard converters to satisfy the basic type conversion needs. and to create an object representation of a string.to create a string representation of an object. <h:outputText value="Your Name:"/> <h:inputText id="helloInput" value="#{helloBean.7 Validators and Converters JSF supports validation and conversion through validator or conversion methods of backing beans and validator and converter objects. 1980. an error message is generated for that specific component. These error messages can then be displayed back to users with a <h:message> or <h:messages> tag. and third-party vendors will provide them as well. As with validators. on the other hand. is much more than just a string. 7.name}"> <f:validateLength minimum="2" maximum="10"/> </h:inputText> <h:message for="helloInput" styleClass="errorMessage"/> <f:validateLongRange> and <f:validateDoubleRange> can be used to ensure that the (long/double) value inserted in the input field is greater than or equal to the specified maximum (long/double) value (smaller than or equal to the minimum value). converters create converter exceptions and send them back to the user as faces messages. Validation checks the value of a control to see if its current value is acceptable.dateOfBirth}"> <f:validateLongRange minimum="0" maximum="120"/> </h:inputText> <h:message for="helloAge" styleClass="errorMessage"/> 43 . This is the purpose of a converter . You can also write your own converters. Otherwise.

} } 7. */ public static final String INVALID_NAME_MESSAGE_ID = "NameValidator.trim().matches("[A-Z][a-z]*")) { FacesMessage message = MessageFactory.getMessage( FacesMessage. Validation methods are generally used for application specific validation and can not be reused for different applications.3 Validator Classes Validator classes raise some additional work.name}" validator="#{helloBean.SEVERITY_ERROR. public void validate(FacesContext context.INVALID_NAME"). UIComponent component.toString(). The validator interface demands for one method: validate(). <h:inputText id="helloInput" value="#{helloBean. Object value) { if (!value. */ public static final String VALIDATOR_ID = "NameValidator". "NameValidator.getMessage( FacesMessage. On the other hand.toString().matches("[A-Z][a-z]*")) { FacesMessage message = MessageFactory. public class NameValidator implements Validator { /** The identifier of the validator. we have to declare it as validator in the facesconfig. For any input component you can register one or more validators. UIComponent component.7.trim(). INVALID_NAME_MESSAGE_ID).2 Validator Methods An input field can also be associated with a validation method on a backing bean. throw new ValidatorException(message).INVALID_NAME". } } } To ensure that this validator class is instantiated. Object value) { if (!value. /** The identifier of the error message. validator classes are generic and designed for use in different applications.xml file: 44 . throw new ValidatorException(message).nameCheck}"> <f:validateLength minimum="2" maximum="10"/> </h:inputText> The corresponding nameCheck method in the backing bean: public void nameCheck( FacesContext context.SEVERITY_ERROR.

<h:inputText value="#{helloBean.00"/> </h:inputText> We would obtain a similar result by the code: <h:inputText value ="#{helloBean. So for all these types. </navigation-rule> <validator> <validator-id>NameValidator</validator-id> <validator-class>helloWorld. The number converter is useful for displaying numbers in basic formats like a currency or a percentage. BigInteger.4 Automatic Conversion If you don’t specify a converter. Character. </managed-bean> <navigation-rule> .name}"> <f:validator validatorId="NameValidator"/> </h:inputText> 7. and Long.##0. The JSF framework has standard converters for all the basic Java types: BigDecimal. . .<faces-config> <managed-bean> . All primitive types are converted to their object counterparts.NameValidator</validator-class> </validator> </faces-config> This class can then be used as validator in any JSP page: <h:inputText id="helloInput" value="#{helloBean. Integer. #.price}"> <f:convertNumber maxFractionDigits="2"/> </h:inputText> 45 . Boolean. depending on what you want to print out. Double. . The type attribute is optional and can be either date or time or both.price}"> <f:convertNumber pattern="SFr. JSF will pick one for you.5 Standard Converters There are two converter tags: <f:convertDateTime> and <f:convertNumber> <h:inputText value="#{helloBean. Short. conversion is performed automatically. Float. . Byte.dateOfBirth}"> <f:convertDateTime type="date"/> </h:inputText> f:convertDateTime can be used to convert a Date object to a string (and vice versa). 7.

public Object getAsObject(FacesContext context. } public String getAsString(FacesContext context. public class CountryConverter implements Converter { /** The identifier of the converter.xml file: <converter> <converter-id>CountryConverter</converter-id> <converter-class>helloWorld.country}"> <f:converter converterId="CountryConverter"/> </h:inputText> The converter has to be configured in the faces-config.INVALID_COUNTRY_KEY".7. /** The identifier of the error message. the standard converters will be sufficient. } if(countries. throw new ConverterException(message). String> countries.. You have to develop custom converters any time you want to make it easy for a front-end developer to display a special data type. ). they handle all of the standard Java data types. */ public static final String COUNTRY_CONVERTER_MESSAGE_ID = "CountryConverter. return value. or accept input for that special data type. */ public static final String CONVERTER_ID = "CountryConverter". UIComponent component. the user can insert a two letter country code. and also provide sophisticated formatting functionality for dates and numbers. String value) throws ConverterException { if(value..6 Using Custom Converters In many cases. Object value) throws ConverterException { return value.CountryConverter </converter-class> </converter> 46 . which is automatically converted into the corresponding country name.get(value).length() < 2) { FacesMessage message = MessageFactory. } } You can use this converter in the JSP page: <h:inputText id="country" value="#{helloBean.trim(). HashMap<String. UIComponent component. In our example.containsKey(value)) return countries.toString().getMessage( .

> <application> <locale-config> <default-locale>en</default-locale> <supported-locale>de</supported-locale> </locale-config> <message-bundle>messages</message-bundle> <resource-bundle> <base-name>texts</base-name> <var>label</var> </resource-bundle> </application> If the bundles are placed in WEB-INF/classes. Some implementations. . like in the WEB-INF/classes/org/jia directory. If the resource bundle can not find a key. The var attribute specifies the name which is used in your JSF component tags. With JSF 1.texts”.8 Internationalization Enabling an application to support multiple locales is called internationalization.jia. 47 . like the reference implementation. The following tag loads the bundle and stores it in the request scope. prefixed by its location in your classpath. if we had nested them deeper. provide localized messages for validator and converter errors for certain languages (English. 8. <f:view .theKey}.. > <f:loadBundle basename="texts" var="label"/> . .1 you had to define the texts with the <f:loadBundle> tag. However. French and German). Both attributes (basename and var) are required. no prefix is needed. The process of modifying an application to support a (new) locale is called localization.. the basename would be “org.1 Load the Resource Bundle Using a resource bundle in a JSF application is as simple as using a value-binding expression. you can grab a particular string from that bundle with an ordinary value-binding expression such as #{label. it will return the string “??? key ???” instead. <f:view> The basename attribute specifies the name of the resource bundle. . <faces-config . Once the bundle has been loaded. All you have to do is to define the proper resource bundle in the faces-config file. . .

3 Creating Resource Bundles Resource bundles are not a JSF feature—they are a fundamental part of the way Java handles internationalization and localization. texts_de.properties helloWorld=Hello.. ihr alle! yourName=Ihr Name dateOfBirth=Geburtsdatum country=Land hello=Hallo goodMorning=Guten Tag goodbye=Auf Wiedersehen seeYou=Tschüss texts_en.properties helloWorld=Hallo. whether it is in English. French.. </faces-config> 8. So the key „helloWorld“ points to the string that represents the welcome message.8. or German.2 Configuring Locales The first step towards supporting multiple languages is to tell your JSF application which locales it should support and which of the supported locales should be used as the default locale. which is the same for all locales. Each string has a key. Resource bundles are normal property files with key/value pairs. world! yourName=Your Name dateOfBirth=Date of Birth country=Country hello=Hello goodMorning=Good Morning goodbye=Goodbye seeYou=See you 48 . You specify the supported locales with the <locale-config> element in the faces configuration file: <faces-config> <application> <locale-config> <default-locale>en</default-locale> <supported-locale>de</supported-locale> <supported-locale>fr</supported-locale> <supported-locale>it</supported-locale> </locale-config> </application> .

8. } catch (MissingResourceException e) {} return text.4 Using Resource Bundles Once you have created one or more resource bundles. locale).getViewRoot().dateOfBirth}"/> <h:commandButton value="#{label. you will have to make sure that your JSF components use the string in the bundle instead of a hard coded text value: <h:outputText value="#{label.8. } You can use this method to extract the correct string from the bundle: helloText = getText("goodbye") + " " + name + "!".yourName}"/> <h:outputText value="#{label.getCurrentInstance().getBundle("texts". a getText method like the following can be useful: private String getText(String key) { String text = "???" + key + "???".getString(key).goodbye}" action="#{helloBean. Locale locale = context.. The name of your message bundle (here messages) and the supported locales have to be defined in the faces-config. text = bundle. ResourceBundle bundle = ResourceBundle.getLocale(). you can configure an application-wide message bundle.. try { FacesContext context = FacesContext.5 Constructing Localized Messages In order to localize your error or information messages.sayHello}"/> If you need localized texts in your backing beans.xml file: <faces-config> <application> <locale-config> <default-locale>en</default-locale> <supported-locale>en</supported-locale> <supported-locale>de</supported-locale> </locale-config> <message-bundle>messages</message-bundle> </application> . </faces-config> 49 .

MINIMUM_detail=The input value must be at least ''{0}'' characters long.INVALID_COUNTRY_KEY_detail=Land muss ein Ländercode aus 2 Buchstaben sein messages_en. javax.MAXIMUM_detail=Der Eingabewert darf höchstens {0} Zeichen lang sein.validator. CountryConverter. NameValidator.LengthValidator. NameValidator.validator.properties (German message bundle) javax.LengthValidator.MINIMUM_detail=Der Eingabewert muss mindestens {0} Zeichen lang sein. javax.faces.MINIMUM=Die Eingabe ist zu kurz.For each of the supported locales.validator.validator.INVALID_COUNTRY_KEY=Invalid country key.properties (English message bundle) javax.INVALID_NAME=Invalid value for name. you have to provide a corresponding messages_xx.faces.validator.LengthValidator. javax.validator.INVALID_COUNTRY_KEY_detail=Country must be a 2 letter country code JSF will use your bundles to override default validation and conversion error messages.INVALID_NAME=Ungültiger Namenswert. javax.faces.INVALID_COUNTRY_KEY=Ungültiger Ländercode. javax.faces.validator.INVALID_NAME_detail=Namenswert entspricht nicht dem Pattern [A-Z] [a-z]* CountryConverter.faces.LengthValidator.MAXIMUM=Die Eingabe ist zu lang.LengthValidator. NameValidator. javax.LengthValidator.faces. CountryConverter. The corresponding JSP page uses a normal message tag: <h:message for="country" styleClass="errorMessage"/> <h:messages showDetail="true" layout="table" styleClass="errorMessage"/> 50 .LengthValidator. NameValidator.properties file: messages_de.INVALID_NAME_detail=Name value does not match pattern [A-Z][a-z]* CountryConverter.MAXIMUM_detail=The input value can''t be more than ''{0}'' characters long.faces.faces.MINIMUM=Input value too short.validator.LengthValidator.MAXIMUM=Input value too long.

} } We can use this MessageFactory in any backing bean.getString(key + "_detail").getMessageBundle(). locale).matches("[A-Z][a-z]*")) { FacesMessage message = MessageFactory. summary = MessageFormat. Locale locale = context. try { summary = bundle. detail = bundle.INVALID_NAME". ResourceBundle bundle = ResourceBundle. The MessageFactory from chapter has to be changed somewhat to provide us with the desired localized FacesMessage: MessageFactory. SEVERITY_WARN. if (name == null) name = FacesMessage. summary.FACES_MESSAGES. } catch (MissingResourceException e) { } return new FacesMessage(severity. custom converter or custom validator. FacesContext context = FacesContext.getApplication().Severity severity. String key.getMessage( FacesMessage.trim().java public class MessageFactory { public static FacesMessage getMessage(FacesMessage.getViewRoot().getLocale(). validator or converter. public void validate( FacesContext context.getString(key). Object.. you can create a message (of type FacesMessage) by first extracting the client's locale.format(detail. params) { String summary = "?? key " + key + " not found ??". detail). SEVERITY_ERROR. In your backing bean. Object value ) { if (!value.format(summary. params). String detail = null. String name = context. */ public static final String VALIDATOR_ID = "NameValidator".toString(). /** The identifier of the error message. to create localized error messages: public class NameValidator implements Validator { /** The identifier of the validator. The FacesMessage constructor takes the arguments severity (SEVERITY_INFO.6 Using Localized Message Bundles for Application Messages You can also use the message bundle to create your own (error) messages.getCurrentInstance(). the name of the message bundle and from this the summary and detail string of the dedicated message. or SEVERITY_FATAL) summary string and detail string. detail = MessageFormat. */ public static final String INVALID_NAME_MESSAGE_ID = "NameValidator. throw new ValidatorException(message).getBundle(name. } } } 51 . UIComponent component.SEVERITY_ERROR.8. params).. INVALID_NAME_MESSAGE_ID).

52 .

However. you should make sure that there is no alternative way you can reach your goal: you can visit the JSF Central page (www.com). By implementing the StateHolder interface.9 Custom Tags As we’ve already seen. and different IDE vendors provide many additional components. validators. we make sure that the state of the validator (its properties) is saved between different requests. and converters. a regular expression used by a custom validator to match certain input strings <g:validateRegex pattern="[a-z]{5}"/>). renderers. JavaServer Faces has several services that enable you to build web applications quickly. to find out about different JSF products and libraries. The validator Interface requires a public validate() method. These attributes are used as custom properties (e. The following sections show all the details needed to implement a custom validator tag. Many standard components are available already. 9. 53 .1 The different parts of a Custom Tag To create a custom validator tag. With custom tags for validators or converters we are able to provide custom tag attributes.jsfcentral. for example. In this chapter we learn how to create our own custom tags. Custom tags for validators and converters are implemented in the same way. Before you write a new custom tag or custom component. we first have to write a CustomValidator class which implements the Validator and the StateHolder interfaces.g. the real power of JSF lies in its sophisticated component model and an extensible architecture that allows you to create your own user interface (UI) extensions—components.

The Validator Tag Class
The validator tag class has to extend the abstract ValidatorELTag class, which means it has to implement a createValidator() method. Furthermore, the validator tag class needs setter methods for all attributes of the tag. If the custom tag provides any attributes, the tag class should implement a release() method.
public class MyValidatorTag extends ValidatorELTag { public Validator createValidator() throws JspException { . . . // create validator object return validator; } public void release() { // release state super.release(); // set validator properties to null } // setter methods for validator properties }

The createValidator Method
To be able to share the same validator object between different pages, the validator class should be created in the following way.

54

The Tag Library Description File
For the JSP integration we need a Tag-Library description of the new tag (customValidator.tld):
<taglib . . . > <tlib-version>1.0</tlib-version> <short-name> ns-Prefix </short-name> <uri> tag_URI </uri> <tag> <name> tag_name </name> <tag-class> tag_class_name </tag-class> <body-content> normally empty</body-content> <attribute> <description> . . . </description> <name>attribute name</name> <required>true | false</required> <deferred-value> <type>type of attribute</type> </deferred-value> </attribute> </tag>

. . . <taglib>

The Validator Class
public class MyValidator implements Validator, StateHolder { // Custom Validator ID as defined in faces-config.xml file public static String VALIDATOR_ID = CustomValidatorId;
/** The identifier of the error message. */ public static final String MESSAGE_ID = "name of message";

private boolean transientValue = false; // parameters are not transient // implement Validator interface public void validate( FacesContext facesContext, UIComponent uiComponent, Object value) { if (value does not match requirements) { // raise a validator exception FacesMessage message = MessageFactory.getMessage( FacesMessage.SEVERITY_ERROR, MESSAGE_ID, msg.params...); throw new ValidatorException(message); } }
// implement StateHolder interface

public void restoreState(FacesContext fc, Object state) { // read parameters from state } public Object saveState(FacesContext arg0) { // return wrapped parameters in a serializable Object }
// getter and setter methods for all properties and transient value

. . . }

55

In the faces-config.xml file we have to register all custom validators by their id and fully qualified class name: <validator> <validator-id>CustomValidatorId</validator-id> <validator-class>package.CustomValidatorClass</validator-class> </validator>

Configuration Summary

The Directory Structure
The Tag-Library Description files name is arbitrary, as long as it has a *.tld file extension.

56

if (Integer. whose value is compared to this component's value: <mytags:validateGreaterThan compareToId="main:age"/> The GreaterThanValidator Class public class GreaterThanValidator implements Validator.getValue(). the value of the age component must be smaller than the value of the mother's age.toString())) { // raise a validator exception FacesMessage message = MessageFactory.findComponent(compareToId).toString()) <= Integer . if (greaterThanValue == null) return. /** The identifier of the error message. // compareToId is not transient private boolean transientValue = false.SEVERITY_ERROR. greaterThanValue).2 The Greater-Than Validator We implement an example validateGreaterThan tag which compares the values of two components. throw new ValidatorException(message). UIComponent uiComponent. Object value) { if (value == null) return.getMessage( FacesMessage. GREATER_THAN_MESSAGE_ID. ((HtmlInputText) compareToComponent).GREATER_THAN_ERROR".parseInt(greaterThanValue. Here. if (compareToComponent instanceof EditableValueHolder) { Object greaterThanValue = ((EditableValueHolder) compareToComponent) . // id of component whose value is compared to this components value private String compareToId. The validateGreaterThan tag demands a „comparedToId“ attribute to define the (id of the) component.parseInt(value. */ public static final String GREATER_THAN_MESSAGE_ID = "GreaterThanValidator. } } } 57 . // implement Validator interface public void validate(FacesContext facesContext. UIComponent compareToComponent = uiComponent.9. */ public static final String VALIDATOR_ID = "GreaterThanValidator".getLabel(). StateHolder { /** The identifier of the validator.

} // return the compareToId public String getCompareToId() { return compareToId. } // store the value of compareToId public void setCompareToId(String compareToId) { this.// value holder method public void restoreState(FacesContext fc. Object state) { compareToId = (String) state. } } 58 . } // value holder method public Object saveState(FacesContext arg0) { return compareToId. } // value holder method public void setTransient(boolean value) { transientValue = value.compareToId = compareToId. } // value holder method public boolean isTransient() { return transientValue.

getApplication().release().compareToId = compareToId. return validator. } public void release() { super.The GreaterThanValidatorTag Class The ValidatorTag class must implement the createValidator() method as well as a setter method for its properties (compareToId) and a release method. public class GreaterThanValidatorTag extends ValidatorELTag { // attribute of the tag private ValueExpression compareToId.isLiteralText()) cId = compareToId.getExpressionString(). public void setCompareToId(ValueExpression compareToId) { this.createValidator(GreaterThanValidator. } public Validator createValidator() throws JspException { FacesContext context = FacesContext. validator.tld <?xml version="1. else cId = (String) compareToId.getCurrentInstance(). if (compareToId.getValue(context. } } The Tag Library Description: taglib.setCompareToId(cId). String cId.getELContext()).0" encoding="UTF-8" ?> 59 .VALIDATOR_ID). compareToId = null. GreaterThanValidator validator = (GreaterThanValidator) context .

mage}"> <g:validateGreaterThan compareToId="main:age" /> </h:inputText> <h:message for="mothersAge" styleClass="errorMessage" /> .sun. <f:view> <h:form id="main"> .sun.0</tlib-version> <short-name>myTags</short-name> <uri>http://helloWorld/taglib</uri> <tag> <name>validateGreaterThan</name> <tag-class>helloWorld.com/xml/ns/javaee" xmlns:xsi="http://www.com/xml/ns/javaee/web-jsptaglibrary_2_1.com/JSP/Page" xmlns:f="http://java..w3.sun.com/xml/ns/javaee http://java.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.com/jsf/html" xmlns:g="http://helloWorld/taglib"> ..String</type> </deferred-value> </attribute> </tag> . </jsp:root> 10 JSF Custom Components The JSF framework offers a lot of standard components out of the box. The JSF component model 60 .lang.mothersAge}" value="#{helloBean..1" xmlns="http://java.sun.mothersAge}" /> <h:inputText id="mothersAge" label="#{label.. ..<taglib version="2...GreaterThanValidatorTag</tag-class> <body-content>empty</body-content> <attribute> <description>Id of component this field is compared to</description> <name>compareToId</name> <required>true</required> <deferred-value> <type>java.1" xmlns:jsp="http://java.sun. </taglib> The custom tag can then be used in the JSP page like this: <jsp:root version="2.com/jsf/core" xmlns:h="http://java.age}" required="true" /> <h:message for="age" styleClass="errorMessage" /> <h:outputText value="#{label.xsd"> <tlib-version>1.sun.. .yourAge}" value="#{helloBean..yourAge}" /> <h:inputText id="age" label="#{label. <h:outputText value="#{label.

1 The Component Hierarchy StateHolder ValueHolder Editable ValueHolder UIComponent Base id parent children attributes valueExpressions encodeBegin() encodeChildren() encodeEnd() saveState() restoreState() UIOutput localValue value converter UIInput submittedValue validators decode() updateModel() 10.2 Component Data Collections Components have three types of data collections: • attributes which are untyped key/value pairs • value expressions which define bindings to backing bean properties • individual properties with corresponding setter and getter methods The put() and get() methods of the attributes indirectly access the properties and value expressions if available.and the extensible architecture allow to create new components. it must implement the StateHolder interface to save and restore them.g. progress bar) 10. tree view) • support functionality for other markup languages (e.g. sortable data table) • create new types of components (e. file upload) • provide additional functionality (e.g. 61 . If a component defines properties. Writing a custom component is necessary if you want • to support special HTML features (e. But the development of custom components requires special expertise.g.

10. the local value or the value of the associated backing bean property Values during Request Processing PROCESS VALIDATIONS 2: validate() 2a: setValue() 2b: clearSubmittedValue() APPLY REQUEST VALUES 1: decode() 1a: setSubmittedValue() Input Component 3b: setProperty() 5c: getProperty() Backing Bean UPDATE MODEL VALUES 3: updateModel() 3a: getLocalValue() 3c: clearValue() RENDER RESPONSE 5: encodeBegin() 5a: getSubmittedValue() 5b: getValue() INVOKE APPLICAION 4: action() 62 .3 Value Holder The ValueHolder interfaces support a component's values which are used during request processing: • a submitted value which is the value entered by a user and decoded from the request • a local value which is the value after successful processing by any registered converter and validators • a backing bean property to which the local value is transferred through a value expression The getValue() method either returns the submitted value.

UIComponent Base UIComponent ELTag Custom Component uses Custom ComponentTag registers JSF Configuration registers Tag Library Descriptor In this example a custom input component is developed which allows a user to select a number within a range of numbers. Implement the component class by subclassing an appropriate base class (e. the following steps are needed: 1. i.sayHello}" /> </h:from> 63 .hello}" action="#{helloBean.age}" /> .10.e..xml) 3. The custom component may be included in a JSP page using a custom tag which specifies the range of numbers and a value binding for the selected number: <h:form> .g. <h:outputText value="#{label. UIInput) 2.4 Example of a Custom Component In order to develop a custom UI component.. implement a custom tag (tag handler class.age}" /> <g:selectNumber id="helloAge" min="1" max="50" value="#{helloBean. tag library descriptor). Register the class in the JSF application configuration file (faces-config. Integrate the class with JSP... <h:commandButton value="#{label.

writeAttribute("value". if (getValue().get("min"). "number". */ /** Sets the renderer type. Integer max = (Integer)getAttributes(). val. encodeChildren() and encodeEnd(). String> params = context. this).writeAttribute("name".equals(val)) writer.g. */ public void decode(FacesContext context) { Map<String. null). ResponseWriter writer = context. */ public void encodeBegin(FacesContext context) throws IOException { Integer min = (Integer)getAttributes().writeText(val. */ public static final String COMPONENT_TYPE = "SelectNumber". null).get("number"). writer.writeAttribute("selected". } /** Decodes the selected number from the request. which interprets browser input and sets the submitted value of the component public class SelectNumber extends UIInput { /** The identifier of the component. "true".startElement("option". null). null).getRequestParameterMap(). which are called in order to render a component • implements the decode() method. this). writer. String value = params. } } 64 .endElement("select"). writer. } writer.endElement("option"). UIInput) • defines its type as a constant (COMPONENT_TYPE) • sets its renderer type (not necessary for simple components) • defines its family which is used to find an appropriate renderer (usually inherited from the base class) • implements the methods encodeBegin(). val++) { writer. writer.The Component Class: SelectNumber The component class • subclasses an appropriate base class (e.get("max"). val <= max.startElement("select".getExternalContext(). for (int val = min. setSubmittedValue(value).getResponseWriter(). writer. } /** Renders the number selection to the response. public SelectNumber() { setRendererType(null).

The Configuration File: faces-config.. private String max.com/xml/ns/javaee" .HelloBean</managed-bean-class> <managed-bean-scope>session</managed-bean-scope> </managed-bean> . } 65 /** Returns the component type. We need setter methods as well as a release method for those properties. the component has to be declared by specifying its type and its implementation class <?xml version='1. */ /** The value binding. . If the component has attributes or properties which should be exposed as tag attributes. the tag handler class has to define corresponding properties (here min.0' encoding='UTF-8'?> <faces-config version="1. . > <managed-bean> <description>The one and only HelloBean. .SelectNumber</component-class> </component> .sun. and value). The component tag handler associates the tag with a component and with a renderer (if the component does not render itself). . */ private String min.</description> <managed-bean-name>helloBean</managed-bean-name> <managed-bean-class>helloWorld. </faces-config> The Component Tag Handler Class: SelectNumberTag The component tag handler class is derived from the UIComponentELTag class. max. /** The maximum value.xml In the application configuration file.. The setProperties() method maps the properties of the tag class to attributes or value expressions of the component public class SelectNumberTag extends UIComponentELTag { /** The minimum value.2" xmlns="http://java. public String getComponentType() { return SelectNumber.COMPONENT_TYPE.. */ private ValueExpression value. */ . <component> <component-type>SelectNumber</component-type> <component-class>helloWorld.

value = value. */ public String getRendererType() { return null. min = max = null.put("min". component. component.getAttributes(). } 66 .getAttributes(). */ /** Sets the value binding. value./** Returns the renderer type. */ public void setMin(String min) { this. */ } public void release() { super. } /** Sets the maximum value. } public void setProperties(UIComponent component) { super.max = max. */ /** Releases the resources. value = null. } /** Sets the properties of the component. } /** Sets the minimum value. else component.setValueExpression("value".setProperties(component).put("max". if (value. new Integer(min)). */ public void setValue(ValueExpression value) { this. value).put("value".release().isLiteralText()) component.getAttributes(). } public void setMax(String max) { this. new Integer(max)).min = min.getExpressionString()).

> <tlib-version>1.lang.SelectNumberTag) and defines the valid tag attributes (max. value and id).com/JSP/Page" version="2. .sun. the URI of the tag library has to be defined as XML namespace of the tag element. A tag description maps a tag name (here selectNumber) to a tag handler class (here helloWorld.w3.The Tag Library Descriptor: taglib. <?xml version="1.org/1999/xhtml"> <f:view> <h:form> <g:selectNumber min="1" max="10" value="#{helloBean.page contentType="text/html"/> <html xmlns="http://www.sun. .sun.com/jsf/core" xmlns:h="http://java.1" xmlns:f="http://java.SelectNumberTag</tag-class> <body-content>empty</body-content> <attribute> <name>id</name> </attribute> <attribute> <name>min</name> <required>true</required> </attribute> <attribute> <name>max</name> <required>true</required> </attribute> <attribute> <name>value</name> <required>true</required> <deferred-value> <type>java.com/jsf/html" xmlns:g="http://helloWorld/taglib"> <jsp:directive. min.number}"/> <h:commandButton value="Submit"/> </h:form> </f:view> </html> </jsp:root> 67 . <jsp:root xmlns:jsp="http://java.1</tlib-version> <short-name>myTags</short-name> <uri>http://helloWorld/taglib</uri> <tag> <name>selectNumber</name> <tag-class>helloWorld.jsp In the JSP page.0"?> <taglib .tld The tag library descriptor (TLD) groups different JSP tags into a tag library which is identified by a URI.Integer</type> </deferred-value> </attribute> </tag> </taglib> The JSP page: index.

class SelectNumberTag..xml faces-config.class Summary of Select Number Example 68 .jar jsf-component. /WEB-INF/lib jsf-component.tld /jsf/examples SelectNumber.jsp ...jar /META-INF faces-config.xml taglib.xml /WEB-INF/classes .Packaging the Component A custom UI component can be packaged together with the application's web archive or in a separate JAR file which can then be included in an application's web archive jsf-application.. /WEB-INF web.war index.

You're Reading a Free Preview

Descarregar
scribd
/*********** DO NOT ALTER ANYTHING BELOW THIS LINE ! ************/ var s_code=s.t();if(s_code)document.write(s_code)//-->