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

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

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

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

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

Define page navigation in the application configuration resource file In the JSP Page we use the the unified expression language (EL. Add managed bean declarations to the application configuration file (Faces Config). Develop the Model Object (business logic) Develop the backing beans with the properties as well as the used action methods.10) to bind UI component values and objects to backing bean properties or to reference backing bean methods from UI component tags. Section 1. The Faces Servlet is provided by the JSF Application and is responsible for the communication between the server and the clients (Front Controller pattern).1. The configuration file contains the name of the corresponding backing bean. cf. 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. Client Server HTML Page HTTP Faces Servlet JSF View HTML Elements UI Components EL Backing Bean Model Object JSP Page Faces Config 8 .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.

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

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

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

12 .

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

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

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

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

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

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

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

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

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

name}"/> <h:outputText value="Your Age:"/> <h:inputText id="helloAge" value="#{personDetails.w3.3.xml file.sun.com/jsf/html" version="2.com/JSP/Page" xmlns:f="http://java.favoriteNumbers[1]}" size="4"/> <h:inputText value="#{personDetails. The back button leads back to the hello page. <?xml version="1.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.favoriteNumbers[0]}" size="4"/> <h:inputText value="#{personDetails.6 PersonDetails.com/jsf/core" xmlns:h="http://java.jsp The PersonDetails page can be used to change the properties for name.page contentType="text/html"/> <html xmlns="http://www. All of these properties read their initial value at creation time from the faces-config.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. age and the favorite numbers of the given person. 22 . The favorite numbers are saved in an array or vector of integers in the person details backing bean.0" encoding="UTF-8"?> <jsp:root xmlns:jsp="http://java.sun.1"> <jsp:directive.age}" size="4"/> </h:panelGrid> </p> <p> <h:outputText value="Enter your favorite Numbers:"/> <h:panelGrid columns="3" cellpadding="3"> <h:inputText value="#{personDetails.sun.org/1999/xhtml"> <head> <link href="styles.

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

the helloBean backing bean needs a reference to the personDetails backing bean.util.<managed-bean> <description>Detail Information of a person</description> <managed-bean-name>personDetails</managed-bean-name> <managed-bean-class>helloWorld. 24 .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.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.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. The reference to the previously defined managed bean (PersonDatails) can be assigned to the helloBean via a normal JSF EL expression (Dependency Injection).

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

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

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

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

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

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

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

DataModel has two subclasses: ListDataModel and ArrayDataModel. but there are some important differences. } public String getLastName(){ return lastName. 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. .DataModel instead of the previous array of Person.select}" immediate="true"> <h:outputText value="#{person.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. In the JSF table we have to change the following entries: <h:dataTable value="#{personHandler.firstName = firstName.model. 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. } .public String getFirstName(){ return firstName. JSF offers a much easier way to represent tabular data through the abstract DataModel class. These are convenience implementations of the abstract DataModel class with the following properties: 32 . . However. . } public void setFirstName(String firstName){ this. we must figure out which table row the user selected to make the corresponding details available for display. To implement this feature. } 4. </h:column> </h:dataTable> The table looks similar to the previous one.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.lastName}"/> </h:commandLink> </h:column> <h:column> <f:facet name="header"> <h:outputText value="First Name"/> </f:facet> .

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

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). <h:commandButton value="Say Hello" action="#{helloBean. } 34 .4. Because they perform the same operation. their usage is quite similar. return "hello".7 The Command Components The command components represent an action initiated by the user. else helloText = "Good Morning " + name + "!".sayGoodbye}"/> The corresponding action Methods are defined in the backing bean: public String sayHello() { if (age < 11) helloText = "Hello " + name + "!".

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

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

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

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

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

sayHello}"/> <h:commandButton value="Goodbye" action="#{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.<h:outputText value="Your Age"/> <h:inputText id="age" label="Age" value="#{helloBean.country}" required="true"/> <h:message for="country" errorClass="errorStyle" showDetail="false" showSummary="true"/> </h:panelGrid> <h:commandButton value="Hello" 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 .

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

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

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

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

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

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

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

French..3 Creating Resource Bundles Resource bundles are not a JSF feature—they are a fundamental part of the way Java handles internationalization and localization. </faces-config> 8. So the key „helloWorld“ points to the string that represents the welcome message. Resource bundles are normal property files with key/value pairs. whether it is in English.properties helloWorld=Hello.properties helloWorld=Hallo. texts_de. ihr alle! yourName=Ihr Name dateOfBirth=Geburtsdatum country=Land hello=Hallo goodMorning=Guten Tag goodbye=Auf Wiedersehen seeYou=Tschüss texts_en. which is the same for all locales. world! yourName=Your Name dateOfBirth=Date of Birth country=Country hello=Hello goodMorning=Good Morning goodbye=Goodbye seeYou=See you 48 . or German.8.. Each string has a key. 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> .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.

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

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

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

52 .

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

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

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

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

getCurrentInstance().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.getApplication().isLiteralText()) cId = compareToId. } public Validator createValidator() throws JspException { FacesContext context = FacesContext. } } The Tag Library Description: taglib. GreaterThanValidator validator = (GreaterThanValidator) context .0" encoding="UTF-8" ?> 59 .release(). if (compareToId. validator.getExpressionString(). return validator.compareToId = compareToId.getELContext()).tld <?xml version="1.createValidator(GreaterThanValidator.VALIDATOR_ID). compareToId = null. } public void release() { super. String cId. public void setCompareToId(ValueExpression compareToId) { this. public class GreaterThanValidatorTag extends ValidatorELTag { // attribute of the tag private ValueExpression compareToId.setCompareToId(cId). else cId = (String) compareToId.getValue(context.

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

g. 61 .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. If a component defines properties.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. Writing a custom component is necessary if you want • to support special HTML features (e.and the extensible architecture allow to create new components. But the development of custom components requires special expertise.g. sortable data table) • create new types of components (e. file upload) • provide additional functionality (e. it must implement the StateHolder interface to save and restore them. progress bar) 10.g. tree view) • support functionality for other markup languages (e.g.

10.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. 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 .

g. Integrate the class with JSP. i.hello}" action="#{helloBean. 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> . <h:commandButton value="#{label... tag library descriptor).e.10. 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.sayHello}" /> </h:from> 63 . <h:outputText value="#{label...4 Example of a Custom Component In order to develop a custom UI component. implement a custom tag (tag handler class. UIInput) 2.xml) 3. the following steps are needed: 1.age}" /> . Implement the component class by subclassing an appropriate base class (e.age}" /> <g:selectNumber id="helloAge" min="1" max="50" value="#{helloBean. Register the class in the JSF application configuration file (faces-config.

null). writer. */ public void encodeBegin(FacesContext context) throws IOException { Integer min = (Integer)getAttributes().startElement("select". val. this).writeText(val. Integer max = (Integer)getAttributes(). String> params = context. */ public static final String COMPONENT_TYPE = "SelectNumber". public SelectNumber() { setRendererType(null). if (getValue(). "number". writer. } /** 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.getResponseWriter(). writer. encodeChildren() and encodeEnd(). String value = params.g. this). */ public void decode(FacesContext context) { Map<String. val <= max. null).endElement("select"). val++) { writer. } writer. null).writeAttribute("selected".startElement("option".get("min"). } /** Renders the number selection to the response. for (int val = min.endElement("option"). } } 64 . 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(). null).getExternalContext().writeAttribute("value". "true".get("max"). setSubmittedValue(value).equals(val)) writer. ResponseWriter writer = context.The Component Class: SelectNumber The component class • subclasses an appropriate base class (e.getRequestParameterMap().writeAttribute("name". writer. writer. which are called in order to render a component • implements the decode() method. */ /** Sets the renderer type.get("number").

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

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

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

.xml faces-config.jar /META-INF faces-config..xml taglib. /WEB-INF web.. /WEB-INF/lib jsf-component.jar jsf-component.war index.class SelectNumberTag.jsp .tld /jsf/examples SelectNumber.class Summary of Select Number Example 68 .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..

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)//-->