Release 8
Contributed 2018, 2019
The Jakarta EE 8 Tutorial
Copyright © 2017, 2019 Oracle and/or its affiliates. All rights reserved.
This program and the accompanying materials are made available under the terms of the Eclipse Public License v. 2.0, which is available at http://www.eclipse.org/legal/epl-2.0.
SPDX-License-Identifier: EPL-2.0
Oracle and Java are registered trademarks of Oracle and/or its affiliates. Other names may be trademarks of their respective owners.
Intel and Intel Xeon are trademarks or registered trademarks of Intel Corporation. All SPARC trademarks are used under license and are trademarks or registered trademarks of SPARC International, Inc. AMD, Opteron, the AMD logo, and the AMD Opteron logo are trademarks or registered trademarks of Advanced Micro Devices. UNIX is a registered trademark of The Open Group.
1. Preface
This documentation is part of the Java Enterprise Edition contribution to the Eclipse Foundation and is not intended for use in relation to Java Enterprise Edition or Orace GlassFish. The documentation is in the process of being revised to reflect the new Jakarta EE branding. Additional changes will be made as requirements and procedures evolve for Jakarta EE. Where applicable, references to Java EE or Java Enterprise Edition should be considered references to Jakarta EE. Please see the Title page for additional license information. |
This tutorial is a guide to developing enterprise applications for the Jakarta EE 8 Platform, using Eclipse GlassFish Server.
Eclipse GlassFish Server is the leading open-source and
open-community platform for building and deploying next-generation
applications and services. Eclipse GlassFish Server,
developed by the Eclipse GlassFish project open-source community at
https://projects.eclipse.org/projects/ee4j.glassfish
, is a
compatible implementation of
the Jakarta EE 8 platform specification. This lightweight, flexible, and
open-source application server enables organizations not only to
leverage the new capabilities introduced within the Jakarta EE 8
specification, but also to add to their existing capabilities through a
faster and more streamlined development and deployment cycle. GlassFish
Server Open Source Edition is hereafter referred to as GlassFish Server.
1.1. Audience
This tutorial is intended for programmers interested in developing and deploying Jakarta EE 8 applications. It covers the technologies comprising the Jakarta EE platform and describes how to develop Jakarta EE components and deploy them on the Eclipse GlassFish.
1.2. Before You Read This Book
Before proceeding with this tutorial, you should have a good knowledge
of the Java programming language. A good way to get to that point is to
work through the Java Tutorials
(http://docs.oracle.com/javase/tutorial/index.html
).
1.3. Related Documentation
The GlassFish Server documentation set describes deployment planning and
system installation. To obtain the GlassFish Server documentation, go to https://eclipse-ee4j.github.io/glassfish/documentation
.
The Jakarta EE 8 API specification can be viewed at
https://jakarta.ee/specifications/platform/8/
.
Additionally, the Jakarta EE Specifications at
https://jakarta.ee/specifications
might be
useful.
For information about creating enterprise applications in the NetBeans
Integrated Development Environment (IDE), see
https://netbeans.apache.org/kb/
.
For information about Apache Derby for use with GlassFish
Server, see
http://db.apache.org/derby/docs/10.14/adminguide/
.
The GlassFish Samples project is a collection of sample applications
that demonstrate a broad range of Jakarta EE technologies. The (Java EE 8) GlassFish
Samples are available from the GlassFish Samples project page at
https://javaee.github.io/glassfish-samples/
.
1.4. Conventions
The following table describes the typographic conventions that are used in this book.
Convention |
Meaning |
Example |
Boldface |
Boldface type indicates graphical user interface elements associated with an action or terms defined in text. |
From the File menu, choose Open Project. A cache is a copy that is stored locally. |
|
Monospace type indicates the names of files and directories, commands within a paragraph, URLs, code in examples, text that appears on the screen, or text that you enter. |
Edit your Use
|
Italic |
Italic type indicates book titles, emphasis, or placeholder variables for which you supply particular values. |
Read Chapter 6 in the User’s Guide. Do not save the file. The command to remove a file is |
1.5. Default Paths and File Names
The following table describes the default paths and file names that are used in this book.
Placeholder |
Description |
Default Value |
|
Represents the base installation directory for GlassFish Server. |
Installations on the Solaris operating system, Linux operating system, and Mac operating system:
Windows, all installations:
|
|
Represents the parent of the base installation directory for GlassFish Server. |
Installations on the Solaris operating system, Linux operating system, and Mac operating system:
Windows, all installations:
|
|
Represents the base installation directory for the Jakarta EE Tutorial after you download it. |
|
|
Represents the directory in which a domain’s configuration is stored. |
|
2. Introduction
Part I introduces the platform, the tutorial, and the examples.
2.1. Overview
This chapter introduces you to Jakarta EE enterprise application development. Here you will review development basics, learn about the Jakarta EE architecture and APIs, become acquainted with important terms and concepts, and find out how to approach Jakarta EE application programming, assembly, and deployment.
2.1.1. Introduction to Jakarta EE
Developers today increasingly recognize the need for distributed, transactional, and portable applications that leverage the speed, security, and reliability of server-side technology. Enterprise applications provide the business logic for an enterprise. They are centrally managed and often interact with other enterprise software. In the world of information technology, enterprise applications must be designed, built, and produced for less money, with greater speed, and with fewer resources.
With Jakarta EE, development of Java enterprise applications has never been easier or faster. The aim of the Jakarta EE platform is to provide developers with a powerful set of APIs while shortening development time, reducing application complexity, and improving application performance.
The Jakarta EE platform is developed through the Jakarta EE Specification Process. Expert groups composed of interested parties have created Jakarta Specifications to define the various Jakarta EE technologies. The work of the Jakarta Community under the Jakarta Specification Process program helps to ensure Java technology’s standards of stability and cross-platform compatibility.
The Jakarta EE platform uses a simplified programming model. XML deployment descriptors are optional. Instead, a developer can simply enter the information as an annotation directly into a Java source file, and the Jakarta EE server will configure the component at deployment and runtime. These annotations are generally used to embed in a program data that would otherwise be furnished in a deployment descriptor. With annotations, you put the specification information in your code next to the program element affected.
In the Jakarta EE platform, dependency injection can be applied to all resources a component needs, effectively hiding the creation and lookup of resources from application code. Dependency injection can be used in enterprise bean containers, web containers, and application clients. Dependency injection allows the Jakarta EE container to automatically insert references to other required components or resources, using annotations.
This tutorial uses examples to describe the features available in the Jakarta EE platform for developing enterprise applications. Whether you are a new or experienced enterprise developer, you should find the examples and accompanying text a valuable and accessible knowledge base for creating your own solutions.
2.1.2. Jakarta EE 8 Platform Highlights
The key goals of the Jakarta EE 8 platform are to modernize the infrastructure for enterprise Java for the cloud and microservices environments, emphasize HTML5 and HTTP/2 support, enhance ease of development through new Contexts and Dependency Injection features, and further enhance security and reliability of the platform.
The Jakarta EE 8 platform includes the following new features:
-
New technologies, including the following:
-
New object model improvements for JSON Processing (see Jakarta JSON Processing for details), including support for the following:
-
JSON Pointer
-
JSON Patch
-
JSON Merge Patch
-
-
New features for RESTful web services (see Jakarta RESTful Web Services for details)
-
New features for servlets (see Jakarta Servlet Technology for details)
-
New features for Jakarta Server Faces components (see Jakarta Server Faces Technology for details)
-
New Contexts and Dependency Injection features (see Jakarta Contexts and Dependency Injection for details)
-
New Jakarta Bean Validation features (see Jakarta Bean Validation for details)
2.1.3. Jakarta EE Application Model
The Jakarta EE application model begins with the Java programming language and the Java virtual machine. The proven portability, security, and developer productivity they provide form the basis of the application model. Jakarta EE is designed to support applications that implement enterprise services for customers, employees, suppliers, partners, and others who make demands on or contributions to the enterprise. Such applications are inherently complex, potentially accessing data from a variety of sources and distributing applications to a variety of clients.
To better control and manage these applications, the business functions to support these various users are conducted in the middle tier. The middle tier represents an environment that is closely controlled by an enterprise’s information technology department. The middle tier is typically run on dedicated server hardware and has access to the full services of the enterprise.
The Jakarta EE application model defines an architecture for implementing services as multitier applications that deliver the scalability, accessibility, and manageability needed by enterprise-level applications. This model partitions the work needed to implement a multitier service into the following parts:
-
The business and presentation logic to be implemented by the developer
-
The standard system services provided by the Jakarta EE platform
The developer can rely on the platform to provide solutions for the hard systems-level problems of developing a multitier service.
2.1.4. Distributed Multitiered Applications
The Jakarta EE platform uses a distributed multitiered application model for enterprise applications. Application logic is divided into components according to function, and the application components that make up a Jakarta EE application are installed on various machines depending on the tier in the multitiered Jakarta EE environment to which the application component belongs.
Figure 1-1 shows two multitiered Jakarta EE applications divided into the tiers described in the following list. The Jakarta EE application parts shown in Figure 1-1 are presented in Jakarta EE Components.
-
Client-tier components run on the client machine.
-
Web-tier components run on the Jakarta EE server.
-
Business-tier components run on the Jakarta EE server.
-
Enterprise information system (EIS)-tier software runs on the EIS server.
Although a Jakarta EE application can consist of all tiers shown in Figure 1-1, Jakarta EE multitiered applications are generally considered to be three-tiered applications because they are distributed over three locations: client machines, the Jakarta EE server machine, and the database or legacy machines at the back end. Three-tiered applications that run in this way extend the standard two-tiered client-and-server model by placing a multithreaded application server between the client application and back-end storage.
2.1.4.1. Security
Although other enterprise application models require platform-specific security measures in each application, the Jakarta EE security environment enables security constraints to be defined at deployment time. The Java EE platform makes applications portable to a wide variety of security implementations by shielding application developers from the complexity of implementing security features.
The Jakarta EE platform provides standard declarative access control rules that are defined by the developer and interpreted when the application is deployed on the server. Jakarta EE also provides standard login mechanisms so that application developers do not have to implement these mechanisms in their applications. The same application works in a variety of security environments without changing the source code.
2.1.4.2. Jakarta EE Components
Jakarta EE applications are made up of components. A Jakarta EE component is a self-contained functional software unit that is assembled into a Jakarta EE application with its related classes and files and that communicates with other components.
The Jakarta EE specification defines the following Jakarta EE components:
-
Application clients and applets are components that run on the client.
-
Jakarta Servlet, Jakarta Faces, and Jakarta Server Pages technology components are web components that run on the server.
-
Enterprise bean components (enterprise beans) are business components that run on the server.
Jakarta EE components are written in the Java programming language and are compiled in the same way as any program in the language. The differences between Jakarta EE components and "standard" Java classes are that Jakarta EE components are assembled into a Jakarta EE application, they are verified to be well formed and in compliance with the Jakarta EE specification, and they are deployed to production, where they are run and managed by the Jakarta EE server.
2.1.4.3. Jakarta EE Clients
A Jakarta EE client is usually either a web client or an application client.
Web Clients
A web client consists of two parts:
-
Dynamic web pages containing various types of markup language (HTML, XML, and so on), which are generated by web components running in the web tier
-
A web browser, which renders the pages received from the server
A web client is sometimes called a thin client. Thin clients usually do not query databases, execute complex business rules, or connect to legacy applications. When you use a thin client, such heavyweight operations are off-loaded to enterprise beans executing on the Jakarta EE server, where they can leverage the security, speed, services, and reliability of Jakarta EE server-side technologies.
Application Clients
An application client runs on a client machine and provides a way for users to handle tasks that require a richer user interface than can be provided by a markup language. An application client typically has a graphical user interface (GUI) created from the Swing API or the Abstract Window Toolkit (AWT) API, but a command-line interface is certainly possible.
Application clients directly access enterprise beans running in the business tier. However, if application requirements warrant it, an application client can open an HTTP connection to establish communication with a servlet running in the web tier. Application clients written in languages other than Java can interact with Jakarta EE servers, enabling the Jakarta EE platform to interoperate with legacy systems, clients, and non-Java languages.
Applets
A web page received from the web tier can include an embedded applet. Written in the Java programming language, an applet is a small client application that executes in the Java virtual machine installed in the web browser. However, client systems will likely need the Java Plug-in and possibly a security policy file for the applet to successfully execute in the web browser.
Web components are the preferred API for creating a web client program because no plug-ins or security policy files are needed on the client systems. Also, web components enable cleaner and more modular application design because they provide a way to separate applications programming from web page design. Personnel involved in web page design thus do not need to understand Java programming language syntax to do their jobs.
The JavaBeans Component Architecture
The server and client tiers might also include components based on the JavaBeans component architecture (JavaBeans components) to manage the data flow between the following:
-
An application client or applet and components running on the Jakarta EE server
-
Server components and a database
JavaBeans components are not considered Jakarta EE components by the Jakarta EE specification.
JavaBeans components have properties and have get
and set
methods
for accessing those properties. JavaBeans components used in this way
are typically simple in design and implementation but should conform to
the naming and design conventions outlined in the JavaBeans component
architecture.
Jakarta EE Server Communications
Figure 1-2 shows the various elements that can make up the client tier. The client communicates with the business tier running on the Jakarta EE server either directly or, as in the case of a client running in a browser, by going through web pages or servlets running in the web tier.
2.1.4.4. Web Components
Jakarta EE web components are either servlets or web pages created using Jakarta Faces technology and/or Jakarta Server Pages technology. Servlets are Java programming language classes that dynamically process requests and construct responses. Jakarta Server Pages are text-based documents that execute as servlets but allow a more natural approach to creating static content. Jakarta Faces technology builds on servlets and Jakarta Server Pages technology and provides a user interface component framework for web applications.
Static HTML pages and applets are bundled with web components during application assembly but are not considered web components by the Java EE specification. Server-side utility classes can also be bundled with web components and, like HTML pages, are not considered web components.
As shown in Figure 1-3, the web tier, like the client tier, might include a JavaBeans component to manage the user input and send that input to enterprise beans running in the business tier for processing.
2.1.4.5. Business Components
Business code, which is logic that solves or meets the needs of a particular business domain such as banking, retail, or finance, is handled by enterprise beans running in either the business tier or the web tier. Figure 1-4 shows how an enterprise bean receives data from client programs, processes it (if necessary), and sends it to the enterprise information system tier for storage. An enterprise bean also retrieves data from storage, processes it (if necessary), and sends it back to the client program.
2.1.4.6. Enterprise Information System Tier
The enterprise information system tier handles EIS software and includes enterprise infrastructure systems, such as enterprise resource planning (ERP), mainframe transaction processing, database systems, and other legacy information systems. For example, Jakarta EE application components might need access to enterprise information systems for database connectivity.
2.1.5. Jakarta EE Containers
Normally, thin-client multitiered applications are hard to write because they involve many lines of intricate code to handle transaction and state management, multithreading, resource pooling, and other complex low-level details. The component-based and platform-independent Jakarta EE architecture makes applications easy to write because business logic is organized into reusable components. In addition, the Jakarta EE server provides underlying services in the form of a container for every component type. Because you do not have to develop these services yourself, you are free to concentrate on solving the business problem at hand.
2.1.5.1. Container Services
Containers are the interface between a component and the low-level, platform-specific functionality that supports the component. Before it can be executed, a web, enterprise bean, or application client component must be assembled into a Jakarta EE module and deployed into its container.
The assembly process involves specifying container settings for each component in the Jakarta EE application and for the Jakarta EE application itself. Container settings customize the underlying support provided by the Jakarta EE server, including such services as security, transaction management, Java Naming and Directory Interface (JNDI) API lookups, and remote connectivity. Here are some of the highlights.
-
The Jakarta EE security model lets you configure a web component or enterprise bean so that system resources are accessed only by authorized users.
-
The Jakarta EE transaction model lets you specify relationships among methods that make up a single transaction so that all methods in one transaction are treated as a single unit.
-
JNDI lookup services provide a unified interface to multiple naming and directory services in the enterprise so that application components can access these services.
-
The Jakarta EE remote connectivity model manages low-level communications between clients and enterprise beans. After an enterprise bean is created, a client invokes methods on it as if it were in the same virtual machine.
Because the Jakarta EE architecture provides configurable services, components within the same application can behave differently based on where they are deployed. For example, an enterprise bean can have security settings that allow it a certain level of access to database data in one production environment and another level of database access in another production environment.
The container also manages nonconfigurable services, such as enterprise bean and servlet lifecycles, database connection resource pooling, data persistence, and access to the Jakarta EE platform APIs (see Jakarta EE 8 APIs).
2.1.5.2. Container Types
The deployment process installs Jakarta EE application components in the Jakarta EE containers, as illustrated in Figure 1-5.
The server and containers are as follows:
-
Jakarta EE server: The runtime portion of a Jakarta EE product. A Jakarta EE server provides enterprise and web containers.
-
Jakarta Enterprise Bean container: Manages the execution of enterprise beans for Jakarta EE applications. Jakarta Enterprise Beans and their container run on the Jakarta EE server.
-
Web container: Manages the execution of web pages, servlets, and some enterprise bean components for Jakarta EE applications. Web components and their container run on the Jakarta EE server.
-
Application client container: Manages the execution of application client components. Application clients and their container run on the client.
-
Applet container: Manages the execution of applets. Consists of a web browser and a Java Plug-in running on the client together.
2.1.6. Web Services Support
Web services are web-based enterprise applications that use open, XML-based standards and transport protocols to exchange data with calling clients. The Jakarta EE platform provides the XML APIs and tools you need to quickly design, develop, test, and deploy web services and clients that fully interoperate with other web services and clients running on Java-based or non-Java-based platforms.
To write web services and clients with the Jakarta EE XML APIs, all you need to do is pass parameter data to the method calls and process the data returned; for document-oriented web services, you send documents containing the service data back and forth. No low-level programming is needed because the XML API implementations do the work of translating the application data to and from an XML-based data stream that is sent over the standardized XML-based transport protocols. These XML-based standards and protocols are introduced in the following sections.
The translation of data to a standardized XML-based data stream is what makes web services and clients written with the Jakarta EE XML APIs fully interoperable. This does not necessarily mean that the data being transported includes XML tags, because the transported data can itself be plain text, XML data, or any kind of binary data, such as audio, video, maps, program files, computer-aided design (CAD) documents, and the like. The next section introduces XML and explains how parties doing business can use XML tags and schemas to exchange data in a meaningful way.
2.1.6.1. XML
Extensible Markup Language (XML) is a cross-platform, extensible, text-based standard for representing data. Parties that exchange XML data can create their own tags to describe the data, set up schemas to specify which tags can be used in a particular kind of XML document, and use XML style sheets to manage the display and handling of the data.
For example, a web service can use XML and a schema to produce price lists, and companies that receive the price lists and schema can have their own style sheets to handle the data in a way that best suits their needs. Here are examples.
-
One company might put XML pricing information through a program to translate the XML into HTML so that it can post the price lists to its intranet.
-
A partner company might put the XML pricing information through a tool to create a marketing presentation.
-
Another company might read the XML pricing information into an application for processing.
2.1.6.2. SOAP Transport Protocol
Client requests and web service responses are transmitted as Simple Object Access Protocol (SOAP) messages over HTTP to enable a completely interoperable exchange between clients and web services, all running on different platforms and at various locations on the Internet. HTTP is a familiar request-and-response standard for sending messages over the Internet, and SOAP is an XML-based protocol that follows the HTTP request-and-response model.
The SOAP portion of a transported message does the following:
-
Defines an XML-based envelope to describe what is in the message and explain how to process the message
-
Includes XML-based encoding rules to express instances of application-defined data types within the message
-
Defines an XML-based convention for representing the request to the remote service and the resulting response
2.1.6.3. WSDL Standard Format
The Web Services Description Language (WSDL) is a standardized XML format for describing network services. The description includes the name of the service, the location of the service, and ways to communicate with the service. WSDL service descriptions can be published on the Web. Eclipse GlassFish Server provides a tool for generating the WSDL specification of a web service that uses remote procedure calls to communicate with clients.
2.1.7. Jakarta EE Application Assembly and Deployment
A Jakarta EE application is packaged into one or more standard units for deployment to any Jakarta EE platform-compliant system. Each unit contains
-
A functional component or components, such as an enterprise bean, web page, servlet, or applet
-
An optional deployment descriptor that describes its content
Once a Jakarta EE unit has been produced, it is ready to be deployed. Deployment typically involves using a platform’s deployment tool to specify location-specific information, such as a list of local users who can access it and the name of the local database. Once deployed on a local platform, the application is ready to run.
2.1.8. Jakarta EE APIs
The following sections give a brief summary of the technologies required by the Jakarta EE platform and the APIs used in Jakarta EE applications.
2.1.8.1. Jakarta Enterprise Beans Technology
An enterprise bean component, or enterprise bean, is a body of code that has fields and methods to implement modules of business logic. You can think of an enterprise bean as a building block that can be used alone or with other enterprise beans to execute business logic on the Jakarta EE server.
Enterprise beans are either session beans or message-driven beans.
-
A session bean represents a transient conversation with a client. When the client finishes executing, the session bean and its data are gone.
-
A message-driven bean combines features of a session bean and a message listener, allowing a business component to receive messages asynchronously. Commonly, these are Jakarta Messaging messages.
The Jakarta EE 8 platform requires Jakarta Enterprise Beans 3.2 and Jakarta Interceptors 1.2.
2.1.8.2. Jakarta Servlet Technology
Jakarta Servlet technology lets you define HTTP-specific servlet classes. A servlet class extends the capabilities of servers that host applications accessed by way of a request-response programming model. Although servlets can respond to any type of request, they are commonly used to extend the applications hosted by web servers.
In the Jakarta EE 8 platform, new Jakarta Servlet technology features include the following:
-
Server Push
-
HTTP Trailer
The Jakarta EE 8 platform requires Servlet 4.0.
2.1.8.3. Jakarta Faces Technology
Jakarta Faces technology is a user interface framework for building web applications. The main components of Jakarta Faces technology are as follows:
-
A GUI component framework.
-
A flexible model for rendering components in different kinds of HTML or different markup languages and technologies. A
Renderer
object generates the markup to render the component and converts the data stored in a model object to types that can be represented in a view. -
A standard
RenderKit
for generating HTML 4.01 markup.
The following features support the GUI components:
-
Input validation
-
Event handling
-
Data conversion between model objects and components
-
Managed model object creation
-
Page navigation configuration
-
Jakarta Expression Language
All this functionality is available using standard Java APIs and XML-based configuration files.
In the Jakarta EE 8 platform, new features of Jakarta Faces technology include the following:
-
Direct support for WebSockets via the new
<f:websocket>
tag -
Class-level bean validation via the new
<f:validateWholeBean>
tag -
A Jakarta Contexts and Dependency Injection compatible
@ManagedProperty
annotation -
Enhanced component search expression framework
The Jakarta EE 8 platform requires Jakarta Faces 2.3 and Jakarta Expression Language 3.0.
For an excellent summary of what’s new in Jakarta Faces 2.3,
see https://javaserverfaces.github.io/users.html
.
2.1.8.4. Jakarta Server Pages Technology
Jakarta Server Pages technology lets you put snippets of servlet code directly into a text-based document. A Jakarta Server Pages page is a text-based document that contains two types of text:
-
Static data, which can be expressed in any text-based format, such as HTML or XML
-
JSP elements, which determine how the page constructs dynamic content
The Jakarta Server Pages technology is derived from and compatible with the JavaServer Pages (JSP) technology.
For information about JSP technology, see The Java EE 5 Tutorial at
http://docs.oracle.com/javaee/5/tutorial/doc/
.
The Jakarta EE 8 platform requires Jakarta Server Pages 2.3 for compatibility with earlier releases but recommends the use of Facelets as the display technology in new applications.
2.1.8.5. Jakarta Standard Tag Library
The Jakarta Standard Tag Library encapsulates core functionality common to many Jakarta Server Pages applications. Instead of mixing tags from numerous vendors in your Jakarta Server Pages applications, you use a single, standard set of tags. This standardization allows you to deploy your applications on any Jakarta Server Pages container that supports Jakarta Standard Tag Library and makes it more likely that the implementation of the tags is optimized.
Jakarta Standard Tag Library has iterator and conditional tags for handling flow control, tags for manipulating XML documents, internationalization tags, tags for accessing databases using SQL, and tags for commonly used functions.
The Jakarta EE 8 platform requires Jakarta Standard Tag Library 1.2.
2.1.8.6. Jakarta Persistence
Jakarta Persistence is a Java standards–based solution for persistence. Persistence uses an object/relational mapping approach to bridge the gap between an object-oriented model and a relational database. The Jakarta Persistence can also be used in Java SE applications outside of the Jakarta EE environment. Jakarta Persistence consists of the following areas:
-
The Jakarta Persistence
-
The query language
-
Object/relational mapping metadata
The Jakarta EE 8 platform requires Jakarta Persistence 2.2.
2.1.8.7. Jakarta Transactions
Jakarta Transactions provides a standard interface for demarcating transactions. The Jakarta EE architecture provides a default auto commit to handle transaction commits and rollbacks. An auto commit means that any other applications that are viewing data will see the updated data after each database read or write operation. However, if your application performs two separate database access operations that depend on each other, you will want to use the Jakarta Transactions to demarcate where the entire transaction, including both operations, begins, rolls back, and commits.
The Jakarta EE 8 platform requires Jakarta Transactions 1.2.
2.1.8.8. Jakarta RESTful Web Services
Jakarta RESTful Web Services defines APIs for the development of web services built according to the Representational State Transfer (REST) architectural style. A Jakarta RESTful application is a web application that consists of classes packaged as a servlet in a WAR file along with required libraries.
In the Jakarta EE 8 platform, new RESTful web services features include the following:
-
Reactive Client API
When the results of an invocation on a target resource are received, enhancements to the completion stage APIs in Java SE allow the sequence of those results to be specified, prioritized, combined, or concatenated, and how exceptions can be handled.
-
Enhancements in support for server-sent events
Clients may subscribe to server-issued event notifications using a long-running connection. Support for a new media type, text/event-stream, has been added.
-
Support for Jakarta JSON Binding objects, and improved integration with Jakarta Contexts and Dependency Injection, Jakarta Servlet, and Jakarta Bean Validation technologies
The Jakarta EE 8 platform requires Jakarta RESTful Web Services 2.1.
2.1.8.9. Jakarta Managed Beans
Jakarta Managed Beans, lightweight container-managed objects (POJOs) with minimal requirements, support a small set of basic services, such as resource injection, lifecycle callbacks, and interceptors. Managed Beans represent a generalization of the managed beans specified by Jakarta Faces technology and can be used anywhere in a Jakarta EE application, not just in web modules.
The Jakarta Managed Beans specification is part of the Jakarta EE 8 platform specification. The Jakarta EE 8 platform requires Jakarta Managed Beans 1.0.
2.1.8.10. Jakarta Contexts and Dependency Injection
Jakarta Contexts and Dependency Injection (CDI) defines a set of contextual services, provided by Jakarta EE containers, that make it easy for developers to use enterprise beans along with Jakarta Faces technology in web applications. Designed for use with stateful objects, CDI also has many broader uses, allowing developers a great deal of flexibility to integrate different kinds of components in a loosely coupled but typesafe way.
In the Jakarta EE 8 platform, new CDI features include the following:
-
An API for bootstrapping a CDI container in Java SE 8
-
Support for observer ordering, which determines the order in which the observer methods for a particular event are invoked, and support for firing events asynchronously
-
Configurators interfaces, which are used for dynamically defining and modifying CDI objects
-
Built-in annotation literals, a convenience feature for creating instances of annotations, and more
The Jakarta EE 8 platform requires Jakarta Contexts and Dependency Injection 2.0.
2.1.8.11. Jakarta Dependency Injection
Jakarta Dependency Injection defines a standard set of annotations (and one interface) for use on injectable classes.
In the Jakarta EE platform, CDI provides support for Dependency Injection. Specifically, you can use injection points only in a CDI-enabled application.
The Jakarta EE 8 platform requires Jakarta Dependency Injection 1.0.
2.1.8.12. Jakarta Bean Validation
The Jakarta Bean Validation specification defines a metadata model and API for validating data in JavaBeans components. Instead of distributing validation of data over several layers, such as the browser and the server side, you can define the validation constraints in one place and share them across the different layers.
In the Jakarta EE 8 platform, new Jakarta Bean Validation features include the following:
-
Support for new features in Java SE 8, such as the Date-Time API
-
Addition of new built-in Jakarta Bean Validation constraints
The Jakarta EE 8 platform requires Jakarta Bean Validation 2.0.
2.1.8.13. Jakarta Messaging
Jakarta Messaging is a messaging standard that allows Jakarta EE application components to create, send, receive, and read messages. It enables distributed communication that is loosely coupled, reliable, and asynchronous.
The Jakarta EE 8 platform requires Jakarta Messaging 2.0.
2.1.8.14. Jakarta Connectors
The Jakarta Connectors is used by tools vendors and system integrators to create resource adapters that support access to enterprise information systems that can be plugged in to any Jakarta EE product. A resource adapter is a software component that allows Jakarta EE application components to access and interact with the underlying resource manager of the EIS. Because a resource adapter is specific to its resource manager, a different resource adapter typically exists for each type of database or enterprise information system.
The Jakarta Connectors also provides a performance-oriented, secure, scalable, and message-based transactional integration of Jakarta EE platform-based web services with existing EISs that can be either synchronous or asynchronous. Existing applications and EISs integrated through the Jakarta Connectors into the Jakarta EE platform can be exposed as XML-based web services by using Jakarta XML Web Services and Jakarta EE component models. Thus Jakarta XML Web Services and the Jakarta Connectors are complementary technologies for enterprise application integration (EAI) and end-to-end business integration.
The Jakarta EE 8 platform requires Jakarta Connectors 1.7.
2.1.8.15. Jakarta Mail
Jakarta EE applications use the Jakarta Mail to send email notifications. The Jakarta Mail has two parts:
-
An application-level interface used by the application components to send mail
-
A service provider interface
The Jakarta EE platform includes the Jakarta Mail with a service provider that allows application components to send Internet mail.
The Jakarta EE 8 platform requires Jakarta Mail 1.6.
2.1.8.16. Jakarta Authorization
The Jakarta Authorization specification defines a contract between a Jakarta EE application server and an authorization policy provider. All Jakarta EE containers support this contract.
The Jakarta Authorization specification defines java.security.Permission
classes that
satisfy the Jakarta EE authorization model. The specification defines the
binding of container-access decisions to operations on instances of
these permission classes. It defines the semantics of policy providers
that use the new permission classes to address the authorization
requirements of the Jakarta EE platform, including the definition and use
of roles.
The Jakarta EE 8 platform requires Jakarta Authorization 1.5.
2.1.8.17. Jakarta Authentication
The Jakarta Authentication specification defines a service provider interface (SPI) by which authentication providers that implement message authentication mechanisms may be integrated in client or server message-processing containers or runtimes. Authentication providers integrated through this interface operate on network messages provided to them by their calling containers. The authentication providers transform outgoing messages so that the source of each message can be authenticated by the receiving container, and the recipient of the message can be authenticated by the message sender. Authentication providers authenticate each incoming message and return to their calling containers the identity established as a result of the message authentication.
The Jakarta EE 8 platform requires Jakarta Authentication 1.1.
2.1.8.18. Jakarta Security
Jakarta Security specification defines portable, plug-in interfaces for HTTP authentication and identity stores, and an injectable SecurityContext interface that provides an API for programmatic security.
Implementations of the HttpAuthenticationMechanism
interface can be used to
authenticate callers of web applications. An application can supply its own
HttpAuthenticationMechanism
, or use one of the default implementations provided
by the container.
Implementations of the IdentityStore
interface can be used to validate user
credentials and retrieve group information. An application can provide its own
IdentityStore
, or use the built in LDAP or Database store.
The HttpAuthenticationMechanism
and IdentityStore
APIs provide an advantage over
container-provided implementations in that they allow an application to control
the authentication process, and the identity stores used for authentication,
in a standard, portable way.
The SecurityContext
API is intended for use by application code to query and
interact with the current security context. The specification also provides
for default group-to-role mapping, and defines a principal type called
CallerPrincipal
that can represent the identity of an application caller.
The Jakarta EE 8 platform requires Jakarta Security 1.0.
2.1.8.19. Jakarta WebSocket
WebSocket is an application protocol that provides full-duplex communications between two peers over TCP. Jakarta WebSocket enables Jakarta EE applications to create endpoints using annotations that specify the configuration parameters of the endpoint and designate its lifecycle callback methods.
The Jakarta EE 8 platform requires Jakarta WebSocket 1.1.
2.1.8.20. Jakarta JSON Processing
JavaScript Object Notation (JSON) is a text-based data exchange format derived from JavaScript that is used in web services and other connected applications. Jakarta JSON Processing enables Jakarta EE applications to parse, transform, and query JSON data using the object model or the streaming model.
In the Jakarta EE 8 platform, new features of Jakarta JSON Processing include support for the following:
-
JSON Pointer
Defines a string syntax for referencing a specific value within a JSON document. JSON Pointer includes APIs for extracting values from a target document and transforming them to create a new JSON document.
-
JSON Patch
Defines a format for expressing a sequence of operations to be applied to a JSON document.
-
JSON Merge Patch
Defines a format and processing rules for applying operations to a JSON document that are based upon specific content of the target document.
-
The addition of editing and transformation functions to basic JSON document processing.
-
Helper classes and methods, called JSON Collectors, which leverage features of the Stream API that was introduced in Java SE 8.
The Jakarta EE 8 platform requires Jakarta JSON Processing 1.1.
2.1.8.21. Jakarta JSON Binding
Jakarta JSON Binding provides a binding layer for converting Java objects to and from JSON messages. Jakarta JSON Binding also supports the ability to customize the default mapping process used in this binding layer through the use of Java annotations for a given field, JavaBean property, type or package, or by providing an implementation of a property naming strategy.
Jakarta JSON Binding is new to the Jakarta EE 8 platform. The Jakarta EE 8 platform requires Jakarta JSON Binding 1.0.
2.1.8.22. Jakarta Concurrency
Jakarta Concurrency is a standard API for providing asynchronous capabilities to Jakarta EE application components through the following types of objects: managed executor service, managed scheduled executor service, managed thread factory, and context service.
The Jakarta EE 8 platform requires Jakarta Concurrency 1.0.
2.1.8.23. Jakarta Batch
Batch jobs are tasks that can be executed without user interaction. The Batch Applications for the Java Platform specification is a batch framework that provides support for creating and running batch jobs in Java applications. The batch framework consists of a batch runtime, a job specification language based on XML, a Java API to interact with the batch runtime, and a Java API to implement batch artifacts.
The Jakarta EE 8 platform requires Jakarta Batch 1.0.
2.1.9. Jakarta EE 8 APIs in the Java Platform, Standard Edition 8
Several APIs that are required by the Jakarta EE 8 platform are included in the Java Platform, Standard Edition 8 (Java SE 8) and are thus available to Jakarta EE applications.
2.1.9.1. Java Database Connectivity API
The Java Database Connectivity (JDBC) API lets you invoke SQL commands from Java programming language methods. You use the JDBC API in an enterprise bean when you have a session bean access the database. You can also use the JDBC API from a servlet or a JSP page to access the database directly without going through an enterprise bean.
The JDBC API has two parts:
-
An application-level interface used by the application components to access a database
-
A service provider interface to attach a JDBC driver to the Jakarta EE platform
The Jakarta EE 8 platform requires JDBC 4.1.
2.1.9.2. Java Naming and Directory Interface API
The Java Naming and Directory Interface (JNDI) API provides naming and directory functionality, enabling applications to access multiple naming and directory services, such as LDAP, DNS, and NIS. The JNDI API provides applications with methods for performing standard directory operations, such as associating attributes with objects and searching for objects using their attributes. Using JNDI, a Jakarta EE application can store and retrieve any type of named Java object, allowing Jakarta EE applications to coexist with many legacy applications and systems.
Jakarta EE naming services provide application clients, enterprise beans, and web components with access to a JNDI naming environment. A naming environment allows a component to be customized without the need to access or change the component’s source code. A container implements the component’s environment and provides it to the component as a JNDI naming context.
The naming environment provides four logical namespaces: java:comp
,
java:module
, java:app
, and java:global
for objects available to
components, modules, or applications or shared by all deployed
applications. A Jakarta EE component can access named system-provided and
user-defined objects. The names of some system-provided objects, such as
a default JDBC DataSource
object, a default JMS connection factory,
and a JTA UserTransaction
object, are stored in the java:comp
namespace. The Jakarta EE platform allows a component to name user-defined
objects, such as enterprise beans, environment entries, JDBC
DataSource
objects, and messaging destinations.
A Jakarta EE component can also locate its environment naming context by
using JNDI interfaces. A component can create a
javax.naming.InitialContext
object and look up the environment naming
context in InitialContext
under the name java:comp/env
. A
component’s naming environment is stored directly in the environment
naming context or in any of its direct or indirect subcontexts.
2.1.9.3. Jakarta Activation
The Jakarta Activation is used by the Jakarta Mail. Jakarta Activation provides standard services to determine the type of an arbitrary piece of data, encapsulate access to it, discover the operations available on it, and create the appropriate JavaBeans component to perform those operations.
2.1.9.4. Java API for XML Processing
The Java API for XML Processing (JAXP), part of the Java SE platform, supports the processing of XML documents using Document Object Model (DOM), Simple API for XML (SAX), and Extensible Stylesheet Language Transformations (XSLT). JAXP enables applications to parse and transform XML documents independently of a particular XML-processing implementation.
JAXP also provides namespace support, which lets you work with schemas
that might otherwise have naming conflicts. Designed to be flexible,
JAXP lets you use any XML-compliant parser or XSL processor from within
your application and supports the Worldwide Web Consortium (W3C) schema.
You can find information on the W3C schema at
http://www.w3.org/XML/Schema
.
2.1.9.5. Java Architecture for XML Binding
The Java Architecture for XML Binding (JAXB) provides a convenient way to bind an XML schema to a representation in Java language programs. JAXB can be used independently or in combination with Jakarta XML Web Services, in which case it provides a standard data binding for web service messages. All Jakarta EE application client containers, web containers, and Jakarta Enterprise Beans containers support the JAXB API.
The Jakarta EE 8 platform requires JAXB 2.2.
2.1.9.6. Jakarta XML Web Services
The Jakarta XML Web Services specification provides support for web services that use the JAXB API for binding XML data to Java objects. The Jakarta XML Web Services specification defines client APIs for accessing web services as well as techniques for implementing web service endpoints. The Implementing Enterprise Web Services specification describes the deployment of Jakarta XML Web Services based services and clients. The Jakarta Enterprise Beans and Jakarta Servlet specifications also describe aspects of such deployment. Jakarta XML Web Services based applications can be deployed using any of these deployment models.
The Jakarta XML Web Services specification describes the support for message handlers that can process message requests and responses. In general, these message handlers execute in the same container and with the same privileges and execution context as the Jakarta XML Web Services client or endpoint component with which they are associated. These message handlers have access to the same JNDI namespace as their associated component. Custom serializers and deserializers, if supported, are treated in the same way as message handlers.
The Jakarta EE 8 platform requires Jakarta XML Web Services 2.2.
2.1.9.7. Jakarta SOAP with Attachments
The Jakarta SOAP with Attachments is a low-level API on which Jakarta XML Web Services depends. Jakarta SOAP with Attachments enables the production and consumption of messages that conform to the SOAP 1.1 and 1.2 specifications and the Jakarta SOAP with Attachments note. Most developers do not use the Jakarta SOAP with Attachments, instead using the higher-level Jakarta XML Web Services API.
2.1.9.8. Java Authentication and Authorization Service
The Java Authentication and Authorization Service (JAAS) provides a way for a Jakarta EE application to authenticate and authorize a specific user or group of users to run it.
JAAS is a Java programming language version of the standard Pluggable Authentication Module (PAM) framework, which extends the Java platform security architecture to support user-based authorization.
2.1.10. Eclipse GlassFish Server Tools
Eclipse GlassFish Server is a compliant implementation of the Jakarta EE platform. In addition to supporting all the APIs described in the previous sections, Eclipse GlassFish Server includes a number of Jakarta EE tools that are not part of the Jakarta EE platform but are provided as a convenience to the developer.
This section briefly summarizes the tools that make up Eclipse GlassFish Server. Instructions for starting and stopping Eclipse GlassFish Server, starting the Administration Console, and starting and stopping Apache Derby are in Chapter 2, "Using the Tutorial Examples".
Eclipse GlassFish Server contains the tools listed in Table 1-1. Basic usage information for many of the tools appears throughout the tutorial. For detailed information, see the online help in the GUI tools.
Table 1-1 Eclipse GlassFish Server Tools
Tool |
Description |
Administration Console |
A web-based GUI Eclipse GlassFish Server administration utility. Used to stop Eclipse GlassFish Server and to manage users, resources, and applications. |
|
A command-line Eclipse GlassFish Server administration utility. Used to start and stop Eclipse GlassFish Server and to manage users, resources, and applications. |
|
A command-line tool that launches the application client container and invokes the client application packaged in the application client JAR file. |
|
A command-line tool to extract schema information from a database, producing a schema file that Eclipse GlassFish Server can use for container-managed persistence. |
|
A command-line tool to package the application client container libraries and JAR files. |
Apache Derby |
A copy of Apache Derby database. |
|
A command-line tool to transform, or bind, a source XML schema to a set of JAXB content classes in the Java programming language. |
|
A command-line tool to create a schema file for each namespace referenced in your Java classes. |
|
A command-line tool to generate Jakarta XML Web Services portable artifacts for a given WSDL file. After generation, these artifacts can be packaged in a WAR file with the WSDL and schema documents, along with the endpoint implementation, and then deployed. |
|
A command-line tool to read a web service endpoint class and generate all the required Jakarta XML Web Services portable artifacts for web service deployment and invocation. |
2.2. Using the Tutorial Examples
This chapter tells you everything you need to know to install, build, and run the tutorial examples.
For additional samples, see the GlassFish samples at https://github.com/eclipse-ee4j/glassfish-samples/tree/master/ws/javaee8
2.2.1. Required Software
The following software is required to run the examples:
2.2.1.1. Java Platform, Standard Edition
To build, deploy, and run the examples, you need a copy of the Java
Platform, Standard Edition Development Kit (JDK). You must use JDK 8 Update 20 or above. You can download JDK
software from
http://www.oracle.com/technetwork/java/javase/downloads/index.html
.
2.2.1.2. Eclipse Glassfish Server
GlassFish Server 5.1 is targeted as the build and
runtime environment for the tutorial examples. To build, deploy, and run
the examples, you need a copy of GlassFish Server and, optionally,
NetBeans IDE. You can download GlassFish Server from
https://eclipse-ee4j.github.io/glassfish/download
.
GlassFish Server Installation Tips
GlassFish Server is installed from a ZIP file. It sets the
default administration user name as admin
with no required password.
The Admin Port is set to 4848, and the HTTP Port is set to 8080.
This tutorial refers to as-install-parent
, the directory where you
install GlassFish Server. For example, the default installation
directory on Microsoft Windows is C:\glassfish5
, so as-install-parent
is C:\glassfish5
. GlassFish Server itself is installed in as-install
,
the glassfish
directory under as-install-parent
. So on Microsoft
Windows, as-install
is C:\glassfish5\glassfish
.
After you install GlassFish Server, add the following directories to
your PATH
to avoid having to specify the full path when you use
commands:
as-install-parent/bin
as-install/bin
2.2.1.3. Jakarta EE 8 Tutorial Examples
The tutorial example codes are located at https://github.com/eclipse-ee4j/jakartaee-tutorial-examples.
2.2.1.4. NetBeans IDE
The NetBeans integrated development environment (IDE) is a free, open-source IDE for developing Java applications, including enterprise applications. NetBeans IDE supports the Jakarta EE platform. You can build, package, deploy, and run the tutorial examples from within NetBeans IDE.
To run the tutorial examples, you need the latest version of NetBeans
IDE. You can download NetBeans IDE from
https://netbeans.apache.org/download/index.html
. Make sure that you download
the Jakarta EE bundle.
To Install NetBeans IDE without GlassFish Server
When you install NetBeans IDE, do not install the version of GlassFish Server that comes with NetBeans IDE. To skip the installation of GlassFish Server, follow these steps.
-
On the first page of the NetBeans IDE Installer wizard, deselect the check box for GlassFish Server and click OK.
-
Accept both the License Agreement and the Junit License Agreement.
A few of the tutorial examples use the Junit library, so you should install it.
-
Continue with the installation of NetBeans IDE.
To Add GlassFish Server as a Server Using NetBeans IDE
To run the tutorial examples in NetBeans IDE, you must add your GlassFish Server as a server in NetBeans IDE. Follow these instructions to add GlassFish Server to NetBeans IDE.
-
From the Tools menu, choose Servers.
-
In the Servers wizard, click Add Server.
-
Under Choose Server, select GlassFish Server and click Next.
-
Under Server Location, browse to the GlassFish Server installation and click Next.
-
Under Domain Location, select Register Local Domain.
-
Click Finish.
2.2.1.5. Apache Maven
Maven is a Java technology-based build tool developed by the Apache Software Foundation and is used to build, package, and deploy the tutorial examples. To run the tutorial examples from the command line, you need Maven 3.0 or higher. If you do not already have Maven, you can install it from:
Be sure to add the maven-install`/bin` directory to your path.
If you are using NetBeans IDE to build and run the examples, it includes a copy of Maven.
2.2.2. Starting and Stopping GlassFish Server
You can start and stop GlassFish Server using either NetBeans IDE or the command line.
2.2.2.1. To Start GlassFish Server Using NetBeans IDE
-
Click the Services tab.
-
Expand Servers.
-
Right-click the GlassFish Server instance and select Start.
2.2.2.2. To Stop GlassFish Server Using NetBeans IDE
To stop GlassFish Server using NetBeans IDE, right-click the GlassFish Server instance and select Stop.
2.2.2.3. To Start GlassFish Server Using the Command Line
To start GlassFish Server from the command line, open a terminal window or command prompt and execute the following:
asadmin start-domain --verbose
A domain is a set of one or more GlassFish Server instances managed by one administration server. The following elements are associated with a domain:
-
The GlassFish Server port number: The default is 8080.
-
The administration server’s port number: The default is 4848.
-
An administration user name and password: The default user name is
admin
, and by default no password is required.
You specify these values when you install GlassFish Server. The examples in this tutorial assume that you chose the default ports as well as the default user name and lack of password.
With no arguments, the start-domain
command initiates the default
domain, which is domain1
. The --verbose
flag causes all logging and
debugging output to appear on the terminal window or command prompt. The
output also goes into the server log, which is located in
domain-dir`/logs/server.log`.
2.2.3. Starting the Administration Console
To administer GlassFish Server and manage users, resources, and Jakarta EE
applications, use the Administration Console tool. GlassFish Server must
be running before you invoke the Administration Console. To start the
Administration Console, open a browser at http://localhost:4848/
.
2.2.4. Starting and Stopping Apache Derby
GlassFish Server includes Apache Derby.
To start Derby from the command line, open a terminal
window or command prompt, change to the as-install/bin
directory, and execute:
asadmin start-database
To stop Derby from the command line, open a terminal window
or command prompt, change to the as-install/bin
directory, and execute:
asadmin stop-database
For information about Apache Derby included with GlassFish Server, see
the Release Notes that are located in the as-install/javadb/
directory.
2.2.4.1. To Start Derby Using NetBeans IDE
When you start GlassFish Server using NetBeans IDE, the database server starts automatically. If you ever need to start the server manually, however, follow these steps.
-
Click the Services tab.
-
Expand Databases.
-
Right-click Java DB and select Start Server.
Next Steps
To stop the database using NetBeans IDE, right-click Java DB and select Stop Server.
2.2.5. Building the Examples
The tutorial examples are distributed with a configuration file for either NetBeans IDE or Maven. Either NetBeans IDE or Maven may be used to build, package, deploy, and run the examples. Directions for building the examples are provided in each chapter.
2.2.6. Tutorial Example Directory Structure
To facilitate iterative development and keep application source files separate from compiled files, the tutorial examples use the Maven application directory structure.
Each application module has the following structure:
-
pom.xml
: Maven build file -
src/main/java
: Java source files for the module -
src/main/resources
: configuration files for the module, with the exception of web applications -
src/main/webapp
: web pages, style sheets, tag files, and images (web applications only) -
src/main/webapp/WEB-INF
: configuration files for web applications (web applications only)
When an example has multiple application modules packaged into an EAR file, its submodule directories use the following naming conventions:
-
example-name`-app-client`: application clients
-
example-name`-ejb`: enterprise bean JAR files
-
example-name`-war`: web applications
-
example-name`-ear`: enterprise applications
-
example-name`-common`: library JAR containing components, classes, and files used by other modules
The Maven build files (pom.xml
) distributed with the examples contain
goals to compile and assemble the application into the target
directory and deploy the archive to GlassFish Server.
2.2.7. Jakarta EE Maven Archetypes in the Tutorial
Some of the chapters have instructions on how to build an example application using Maven archetypes. Archetypes are templates for generating a particular Maven project. The Tutorial includes several Maven archetypes for generating Jakarta EE projects.
2.2.7.1. Installing the Tutorial Archetypes
You must install the included Maven archetypes into your local Maven repository before you can create new projects based on the archetypes. You can install the archetypes using NetBeans IDE or Maven.
2.2.8. Getting the Latest Updates to the Tutorial
Check for any updates to the tutorial by using the Update Tool included with the Jakarta EE SDK.
2.2.8.1. To Update the Tutorial Using NetBeans IDE
-
Open the Services tab in NetBeans IDE and expand Servers.
-
Right-click the GlassFish Server instance and select View Domain Update Center to display the Update Tool.
-
Select Available Updates in the tree to display a list of updated packages.
-
Look for updates to the Jakarta EE Tutorial (jakartaee-tutorial) package.
-
If there is an updated version of the Tutorial, select Jakarta EE Tutorial (
jakartaee-tutorial
) and click Install.
2.2.8.2. To Update the Tutorial Using the Command Line
-
Open a terminal window and enter the following command to display the Update Tool:
updatetool
-
Select Available Updates in the tree to display a list of updated packages.
-
Look for updates to the Jakarta EE Tutorial (
jakartaee-tutorial
) package. -
If there is an updated version of the tutorial, select Jakarta EE Tutorial (
jakartaee-tutorial
) and click Install.
2.2.9. Debugging Jakarta EE Applications
This section explains how to determine what is causing an error in your application deployment or execution.
2.2.9.1. Using the Server Log
One way to debug applications is to look at the server log in
domain-dir/logs/server.log
. The log contains output from GlassFish
Server and your applications. You can log messages from any Java class
in your application with System.out.println
and the Java Logging APIs
(documented at
http://docs.oracle.com/javase/8/docs/technotes/guides/logging/index.html
)
and from web components with the ServletContext.log
method.
If you use NetBeans IDE, logging output appears in the Output window as well as the server log.
If you start GlassFish Server with the --verbose
flag, all logging and
debugging output will appear on the terminal window or command prompt
and the server log. If you start GlassFish Server in the background,
debugging information is available only in the log. You can view the
server log with a text editor or with the Administration Console log
viewer.
To Use the Administration Console Log Viewer
-
Select the GlassFish Server node.
-
Click View Log Files.
The log viewer opens and displays the last 40 entries.
-
To display other entries, follow these steps:
-
Click Modify Search.
-
Specify any constraints on the entries you want to see.
-
Click Search at the top of the log viewer.
-
2.2.9.2. Using a Debugger
GlassFish Server supports the Java Platform Debugger Architecture (JPDA). With JPDA, you can configure GlassFish Server to communicate debugging information using a socket.
To Debug an Application Using a Debugger
-
Follow these steps to enable debugging in GlassFish Server using the Administration Console:
-
Expand the Configurations node, then expand the server-config node.
-
Select the JVM Settings node. The default debug options are set to:
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=9009
As you can see, the default debugger socket port is 9009. You can change it to a port not in use by GlassFish Server or another service.
-
Select the Debug Enabled check box.
-
Click Save.
-
-
Stop GlassFish Server and then restart it.
3. Platform Basics
Part II introduces platform basics.
3.1. Resource Creation
A resource is a program object that provides connections to such systems as database servers and messaging systems. Jakarta EE components can access a wide variety of resources, including databases, mail sessions, Jakarta Messaging objects, and URLs. The Jakarta EE platform provides mechanisms that allow you to access all these resources in a similar manner. This chapter examines several types of resources and explains how to create them.
3.1.1. Resources and JNDI Naming
In a distributed application, components need to access other components and resources, such as databases. For example, a servlet might invoke remote methods on an enterprise bean that retrieves information from a database. In the Jakarta EE platform, the Java Naming and Directory Interface (JNDI) naming service enables components to locate other components and resources.
A resource is a program object that provides connections to systems,
such as database servers and messaging systems. (A Java Database
Connectivity resource is sometimes referred to as a data source.) Each
resource object is identified by a unique, people-friendly name, called
the JNDI name. For example, the JNDI name of the preconfigured JDBC
resource for Apache Derby shipped with GlassFish Server
is java:comp/DefaultDataSource
.
An administrator creates resources in a JNDI namespace. In GlassFish
Server, you can use either the Administration Console or the asadmin
command to create resources. Applications then use annotations to inject
the resources. If an application uses resource injection, GlassFish
Server invokes the JNDI API, and the application is not required to do
so. However, it is also possible for an application to locate resources
by making direct calls to the JNDI API.
A resource object and its JNDI name are bound together by the naming and
directory service. To create a new resource, a new name/object binding
is entered into the JNDI namespace. You inject resources by using the
@Resource
annotation in an application.
You can use a deployment descriptor to override the resource mapping that you specify in an annotation. Using a deployment descriptor allows you to change an application by repackaging it rather than by both recompiling the source files and repackaging. However, for most applications a deployment descriptor is not necessary.
3.1.2. DataSource Objects and Connection Pools
To store, organize, and retrieve data, most applications use a
relational database. Jakarta EE components may access relational
databases through the JDBC API. For information on this API, see
http://docs.oracle.com/javase/8/docs/technotes/guides/jdbc/
.
In the JDBC API, databases are accessed by using DataSource
objects. A
DataSource
has a set of properties that identify and describe the
real-world data source that it represents. These properties include such
information as the location of the database server, the name of the
database, the network protocol to use to communicate with the server,
and so on. In GlassFish Server, a data source is called a JDBC resource.
Applications access a data source by using a connection, and a
DataSource
object can be thought of as a factory for connections to
the particular data source that the DataSource
instance represents. In
a basic DataSource
implementation, a call to the getConnection
method returns a connection object that is a physical connection to the
data source.
A DataSource
object may be registered with a JNDI naming service. If
so, an application can use the JNDI API to access that DataSource
object, which can then be used to connect to the data source it
represents.
DataSource
objects that implement connection pooling also produce a
connection to the particular data source that the DataSource
class
represents. The connection object that the getConnection
method
returns is a handle to a PooledConnection
object rather than a
physical connection. An application uses the connection object in the
same way that it uses a connection. Connection pooling has no effect on
application code except that a pooled connection, like all connections,
should always be explicitly closed. When an application closes a
connection that is pooled, the connection is returned to a pool of
reusable connections. The next time getConnection
is called, a handle
to one of these pooled connections will be returned if one is available.
Because connection pooling avoids creating a new physical connection
every time one is requested, applications can run significantly faster.
A JDBC connection pool is a group of reusable connections for a particular database. Because creating each new physical connection is time consuming, the server maintains a pool of available connections to increase performance. When it requests a connection, an application obtains one from the pool. When an application closes a connection, the connection is returned to the pool.
Applications that use Jakarta Persistence specify the DataSource
object they are using in the jta-data-source
element of the
persistence.xml
file:
<jta-data-source>jdbc/MyOrderDB</jta-data-source>
This is typically the only reference to a JDBC object for a persistence unit. The application code does not refer to any JDBC objects.
3.1.3. Creating Resources Administratively
Before you deploy or run many applications, you may need to create
resources for them. An application can include a
glassfish-resources.xml
file that can be used to define resources for
that application and others. You can then use the asadmin
command,
specifying as the argument a file named glassfish-resources.xml
, to
create the resources administratively, as shown.
asadmin add-resources glassfish-resources.xml
The glassfish-resources.xml
file can be created in any project using
NetBeans IDE or by hand. Some of the Jakarta Messaging examples use this approach to
resource creation. A file for creating the resources needed for the Messaging
simple producer example can be found in the
jms/simple/producer/src/main/setup
directory.
You could also use the asadmin create-jms-resource
command to create
the resources for this example. When you are done using the resources,
you would use the asadmin list-jms-resources
command to display their
names, and the asadmin delete-jms-resource
command to remove them,
regardless of the way you created the resources.
3.2. Injection
This chapter provides an overview of injection in Jakarta EE and describes the two injection mechanisms provided by the platform: resource injection and dependency injection.
Jakarta EE provides injection mechanisms that enable your objects to obtain references to resources and other dependencies without having to instantiate them directly. You declare the required resources and other dependencies in your classes by decorating fields or methods with one of the annotations that mark the field as an injection point. The container then provides the required instances at runtime. Injection simplifies your code and decouples it from the implementations of its dependencies.
3.2.1. Resource Injection
Resource injection enables you to inject any resource available in the JNDI namespace into any container-managed object, such as a servlet, an enterprise bean, or a managed bean. For example, you can use resource injection to inject data sources, connectors, or custom resources available in the JNDI namespace.
The type you use for the reference to the injected instance is usually an interface, which decouples your code from the implementation of the resource.
For example, the following code injects a data source object that provides connections to the default Apache Derby database shipped with GlassFish Server:
public class MyServlet extends HttpServlet {
@Resource(name="java:comp/DefaultDataSource")
private javax.sql.DataSource dsc;
...
}
In addition to field-based injection as in the preceding example, you can inject resources using method-based injection:
public class MyServlet extends HttpServlet {
private javax.sql.DataSource dsc;
...
@Resource(name="java:comp/DefaultDataSource")
public void setDsc(java.sql.DataSource ds) {
dsc = ds;
}
}
To use method-based injection, the setter method must follow the
JavaBeans conventions for property names: The method name must begin
with set
, have a void
return type, and have only one parameter.
The @Resource
annotation is in the javax.annotation
package and is
defined in the Jakarta Annotations spec. Resource
injection resolves by name, so it is not typesafe: the type of the
resource object is not known at compile time, so you can get runtime
errors if the types of the object and its reference do not match.
3.2.2. Dependency Injection
Dependency injection enables you to turn regular Java classes into managed objects and to inject them into any other managed object. Using dependency injection, your code can declare dependencies on any managed object. The container automatically provides instances of these dependencies at the injection points at runtime, and it also manages the lifecycle of these instances for you.
Dependency injection in Jakarta EE defines scopes, which determine the lifecycle of the objects that the container instantiates and injects. For example, a managed object that is only needed to respond to a single client request (such as a currency converter) has a different scope than a managed object that is needed to process multiple client requests within a session (such as a shopping cart).
You can define managed objects (also called managed beans) that you can later inject by assigning a scope to a regular class:
@javax.enterprise.context.RequestScoped
public class CurrencyConverter { ... }
Use the javax.inject.Inject
annotation to inject managed beans; for
example:
public class MyServlet extends HttpServlet {
@Inject CurrencyConverter cc;
...
}
As opposed to resource injection, dependency injection is typesafe because it resolves by type. To decouple your code from the implementation of the managed bean, you can reference the injected instances using an interface type and have your managed bean implement that interface.
For more information about dependency injection, see Chapter 25, "Introduction to Jakarta Contexts and Dependency Injection" and the Jakarta Contexts and Dependency Injection spec.
3.2.3. The Main Differences between Resource Injection and Dependency Injection
Table 4-1 lists the main differences between resource injection and dependency injection.
Table 4-1 Differences between Resource Injection and Dependency Injection
Injection Mechanism |
Can Inject JNDI Resources Directly |
Can Inject Regular Classes Directly |
Resolves By |
Typesafe |
Resource Injection |
Yes |
No |
Resource name |
No |
Dependency Injection |
No |
Yes |
Type |
Yes |
3.3. Packaging
This chapter describes packaging. A Jakarta EE application is packaged into one or more standard units for deployment to any Jakarta EE platform-compliant system. Each unit contains a functional component or components, such as an enterprise bean, web page, servlet, or applet, and an optional deployment descriptor that describes its content.
3.3.1. Packaging Applications
A Jakarta EE application is delivered in a Java Archive (JAR) file, a Web
Archive (WAR) file, or an Enterprise Archive (EAR) file. A WAR or EAR
file is a standard JAR (.jar
) file with a .war
or .ear
extension.
Using JAR, WAR, and EAR files and modules makes it possible to assemble
a number of different Jakarta EE applications using some of the same
components. No extra coding is needed; it is only a matter of assembling
(or packaging) various Jakarta EE modules into Jakarta EE JAR, WAR, or EAR
files.
An EAR file (see Figure 5-1) contains Jakarta EE modules
and, optionally, deployment descriptors. A deployment descriptor, an XML
document with an .xml
extension, describes the deployment settings of
an application, a module, or a component. Because deployment descriptor
information is declarative, it can be changed without the need to modify
the source code. At runtime, the Jakarta EE server reads the deployment
descriptor and acts upon the application, module, or component
accordingly.
Deployment information is most commonly specified in the source code by annotations. Deployment descriptors, if present, override what is specified in the source code.
The two types of deployment descriptors are Jakarta EE and runtime. A Jakarta
EE deployment descriptor is defined by a Jakarta EE specification and can
be used to configure deployment settings on any Jakarta EE-compliant
implementation. A runtime deployment descriptor is used to configure
Jakarta EE implementation-specific parameters. For example, the GlassFish
Server runtime deployment descriptor contains such information as the
context root of a web application as well as GlassFish Server
implementation-specific parameters, such as caching directives. The
GlassFish Server runtime deployment descriptors are named
glassfish-`moduleType
.xml` and are located in the same META-INF
directory as the Jakarta EE deployment descriptor.
A Jakarta EE module consists of one or more Jakarta EE components for the same container type and, optionally, one component deployment descriptor of that type. An enterprise bean module deployment descriptor, for example, declares transaction attributes and security authorizations for an enterprise bean. A Jakarta EE module can be deployed as a stand-alone module.
Jakarta EE modules are of the following types:
-
Enterprise bean modules, which contain class files for enterprise beans and, optionally, an enterprise bean deployment descriptor. Enterprise bean modules are packaged as JAR files with a
.jar
extension. -
Web modules, which contain servlet class files, web files, supporting class files, GIF and HTML files, and, optionally, a web application deployment descriptor. Web modules are packaged as JAR files with a
.war
(web archive) extension. -
Application client modules, which contain class files and, optionally, an application client deployment descriptor. Application client modules are packaged as JAR files with a
.jar
extension. -
Resource adapter modules, which contain all Java interfaces, classes, native libraries, and, optionally, a resource adapter deployment descriptor. Together, these implement the Connector architecture (see Jakarta EE Connector Architecture) for a particular EIS. Resource adapter modules are packaged as JAR files with an
.rar
(resource adapter archive) extension.
3.3.2. Packaging Enterprise Beans
This section explains how enterprise beans can be packaged in enterprise bean JAR or WAR modules. It includes the following sections:
3.3.2.1. Packaging Enterprise Beans in enterprise bean JAR Modules
An enterprise bean JAR file is portable and can be used for various applications.
To assemble a Jakarta EE application, package one or more modules, such as enterprise bean JAR files, into an EAR file, the archive file that holds the application. When deploying the EAR file that contains the enterprise bean’s enterprise bean JAR file, you also deploy the enterprise bean to GlassFish Server. You can also deploy an enterprise bean JAR that is not contained in an EAR file. Figure 5-2 shows the contents of an enterprise bean JAR file.
3.3.2.2. Packaging Enterprise Beans in WAR Modules
Enterprise beans often provide the business logic of a web application. In these cases, packaging the enterprise bean within the web application’s WAR module simplifies deployment and application organization. Enterprise beans may be packaged within a WAR module as Java programming language class files or within a JAR file that is bundled within the WAR module.
To include enterprise bean class files in a WAR module, the class files
should be in the WEB-INF/classes
directory.
To include a JAR file that contains enterprise beans in a WAR module,
add the JAR to the WEB-INF/lib
directory of the WAR module.
WAR modules that contain enterprise beans do not require an
ejb-jar.xml
deployment descriptor. If the application uses
ejb-jar.xml
, it must be located in the WAR module’s WEB-INF
directory.
JAR files that contain enterprise bean classes packaged within a WAR
module are not considered enterprise bean JAR files, even if the bundled JAR file
conforms to the format of an enterprise bean JAR file. The enterprise beans
contained within the JAR file are semantically equivalent to enterprise
beans located in the WAR module’s WEB-INF/classes
directory, and the
environment namespace of all the enterprise beans are scoped to the WAR
module.
For example, suppose that a web application consists of a shopping cart enterprise bean, a credit card–processing enterprise bean, and a Java servlet front end. The shopping cart bean exposes a local, no-interface view and is defined as follows:
package com.example.cart;
@Stateless
public class CartBean { ... }
The credit card–processing bean is packaged within its own JAR file,
cc.jar
, exposes a local, no-interface view, and is defined as follows:
package com.example.cc;
@Stateless
public class CreditCardBean { ... }
The servlet, com.example.web.StoreServlet
, handles the web front end
and uses both CartBean
and CreditCardBean
. The WAR module layout for
this application is as follows:
WEB-INF/classes/com/example/cart/CartBean.class
WEB-INF/classes/com/example/web/StoreServlet
WEB-INF/lib/cc.jar
WEB-INF/ejb-jar.xml
WEB-INF/web.xml
3.3.3. Packaging Web Archives
In the Jakarta EE architecture, a web module is the smallest deployable and usable unit of web resources. A web module contains web components and static web content files, such as images, which are called web resources. A Jakarta EE web module corresponds to a web application as defined in the Jakarta Servlet specification.
In addition to web components and web resources, a web module can contain other files:
-
Server-side utility classes, such as shopping carts
-
Client-side classes, such as utility classes
A web module has a specific structure. The top-level directory of a web module is the document root of the application. The document root is where XHTML pages, client-side classes and archives, and static web resources, such as images, are stored.
The document root contains a subdirectory named WEB-INF
, which can
contain the following files and directories:
-
classes
, a directory that contains server-side classes: servlets, enterprise bean class files, utility classes, and JavaBeans components -
lib
, a directory that contains JAR files that contain enterprise beans, and JAR archives of libraries called by server-side classes -
Deployment descriptors, such as
web.xml
(the web application deployment descriptor) andejb-jar.xml
(an enterprise bean deployment descriptor)
A web module needs a web.xml
file if it uses Jakarta Server Faces
technology, if it must specify certain kinds of security information, or
if you want to override information specified by web component
annotations.
You can also create application-specific subdirectories (that is,
package directories) in either the document root or the
WEB-INF/classes/
directory.
A web module can be deployed as an unpacked file structure or can be
packaged in a JAR file known as a Web Archive (WAR) file. Because the
contents and use of WAR files differ from those of JAR files, WAR file
names use a .war
extension. The web module just described is portable;
you can deploy it into any web container that conforms to the Jakarta
Servlet specification.
You can provide a runtime deployment descriptor (DD) when you deploy a
WAR on GlassFish Server, but it is not required under most
circumstances. The runtime DD is an XML file that may contain such
information as the context root of the web application, the mapping of
the portable names of an application’s resources to GlassFish Server
resources, and the mapping of an application’s security roles to users,
groups, and principals defined in GlassFish Server. The GlassFish Server
web application runtime DD, if used, is named glassfish-web.xml
and is
located in the WEB-INF
directory. The structure of a web module that
can be deployed on GlassFish Server is shown in Figure
5-3.
3.3.4. Packaging Resource Adapter Archives
A Resource Adapter Archive (RAR) file stores XML files, Java classes, and other objects for Jakarta EE Connector applications. A resource adapter can be deployed on any Jakarta EE server, much like a Jakarta EE application. A RAR file can be contained in an Enterprise Archive (EAR) file, or it can exist as a separate file.
The RAR file contains
-
A JAR file with the implementation classes of the resource adapter
-
An optional
META-INF/
directory that can store anra.xml
file and/or an application server–specific deployment descriptor used for configuration purposes
A RAR file can be deployed on the application server as a standalone component or as part of a larger application. In both cases, the adapter is available to all applications using a lookup procedure.
4. The Web Tier
Part III explores the technologies in the web tier.
4.1. Getting Started with Web Applications
This chapter introduces web applications, which typically use JavaServer Faces technology and/or Java Servlet technology.
4.1.1. Web Applications
A web application is a dynamic extension of a web or application server. Web applications are of the following types:
-
Presentation-oriented: A presentation-oriented web application generates interactive web pages containing various types of markup language (HTML, XHTML, XML, and so on) and dynamic content in response to requests. Development of presentation-oriented web applications is covered in Chapter 7, "Jakarta Server Faces Technology," through Chapter 18, "Jakarta Servlet Technology."
-
Service-oriented: A service-oriented web application implements the endpoint of a web service. Presentation-oriented applications are often clients of service-oriented web applications. Development of service-oriented web applications is covered in Chapter 31, "Building Web Services with JAX-WS," and Chapter 32, "Building RESTful Web Services with Jakarta RESTful Web Services," in Part III, "Web Services."
In the Jakarta EE platform, web components provide the dynamic extension
capabilities for a web server. Web components can be Jakarta servlets, web
pages implemented with Jakarta Server Faces technology, web service
endpoints, or Jakarta Server pages. Figure 6-1 illustrates the
interaction between a web client and a web application that uses a
servlet. The client sends an HTTP request to the web server. A web
server that implements Jakarta Servlet and Jakarta Server Pages technology
converts the request into an HTTPServletRequest
object. This object is
delivered to a web component, which can interact with JavaBeans
components or a database to generate dynamic content. The web component
can then generate an HTTPServletResponse
or can pass the request to
another web component. A web component eventually generates a
HTTPServletResponse
object. The web server converts this object to an
HTTP response and returns it to the client.
Servlets are Java programming language classes that dynamically process requests and construct responses. Java technologies, such as Jakarta Server Faces and Facelets, are used for building interactive web applications. (Frameworks can also be used for this purpose.) Although servlets and Jakarta Server Faces and Facelets pages can be used to accomplish similar things, each has its own strengths. Servlets are best suited for service-oriented applications (web service endpoints can be implemented as servlets) and the control functions of a presentation-oriented application, such as dispatching requests and handling nontextual data. Jakarta Server Faces and Facelets pages are more appropriate for generating text-based markup, such as XHTML, and are generally used for presentation-oriented applications.
Web components are supported by the services of a runtime platform called a web container. A web container provides such services as request dispatching, security, concurrency, and lifecycle management. A web container also gives web components access to such APIs as naming, transactions, and email.
Certain aspects of web application behavior can be configured when the application is installed, or deployed, to the web container. The configuration information can be specified using Jakarta EE annotations or can be maintained in a text file in XML format called a web application deployment descriptor (DD). A web application DD must conform to the schema described in the Jakarta Servlet specification.
This chapter gives a brief overview of the activities involved in developing web applications. First, it summarizes the web application lifecycle and explains how to package and deploy very simple web applications on GlassFish Server. The chapter then moves on to configuring web applications and discusses how to specify the most commonly used configuration parameters.
4.1.2. Web Application Lifecycle
A web application consists of web components; static resource files, such as images and cascading style sheets (CSS); and helper classes and libraries. The web container provides many supporting services that enhance the capabilities of web components and make them easier to develop. However, because a web application must take these services into account, the process for creating and running a web application is different from that of traditional stand-alone Java classes.
The process for creating, deploying, and executing a web application can be summarized as follows:
-
Develop the web component code.
-
Develop the web application deployment descriptor, if necessary.
-
Compile the web application components and helper classes referenced by the components.
-
Optionally, package the application into a deployable unit.
-
Deploy the application into a web container.
-
Access a URL that references the web application.
Developing web component code is covered in the later chapters. Steps 2 through 4 are expanded on in the following sections and illustrated with a Hello, World–style, presentation-oriented application. This application allows a user to enter a name into an HTML form and then displays a greeting after the name is submitted.
The Hello application contains two web components that generate the greeting and the response. This chapter discusses the following simple applications:
-
hello1
, a Jakarta Server Faces technology–based application that uses two XHTML pages and a managed bean -
hello2
, a servlet-based web application in which the components are implemented by two servlet classes
The applications are used to illustrate tasks involved in packaging, deploying, configuring, and running an application that contains web components.
4.1.3. A Web Module That Uses Jakarta Server Faces Technology: The hello1 Example
The hello1
application is a web module that uses Jakarta Server Faces
technology to display a greeting and response. You can use a text editor
to view the application files, or you can use NetBeans IDE.
The source code for this application is in the
tut-install/examples/web/jsf/hello1/
directory.
4.1.3.1. To View the hello1 Web Module Using NetBeans IDE
To view the hello1
web module using NetBeans IDE:
-
From the File menu, choose Open Project.
-
In the Open Project dialog box, navigate to:
tut-install/examples/web/jsf
-
Select the
hello1
folder and click Open Project. -
Expand the Web Pages node and double-click the
index.xhtml
file to view it in the editor.The
index.xhtml
file is the default landing page for a Facelets application. In a typical Facelets application, web pages are created in XHTML. For this application, the page uses simple tag markup to display a form with a graphic image, a header, a field, and two command buttons:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"> <h:head> <title>Facelets Hello Greeting</title> </h:head> <h:body> <h:form> <h:graphicImage url="#{resource['images:duke.waving.gif']}" alt="Duke waving his hand"/> <h2>Hello, my name is Duke. What's yours?</h2> <h:inputText id="username" title="My name is: " value="#{hello.name}" required="true" requiredMessage="Error: A name is required." maxlength="25" /> <p></p> <h:commandButton id="submit" value="Submit" action="response"> </h:commandButton> <h:commandButton id="reset" value="Reset" type="reset"> </h:commandButton> </h:form> ... </h:body> </html>
The most complex element on the page is the
inputText
field. Themaxlength
attribute specifies the maximum length of the field. Therequired
attribute specifies that the field must be filled out; therequiredMessage
attribute provides the error message to be displayed if the field is left empty. Thetitle
attribute provides the text to be used by screen readers for the visually disabled. Finally, thevalue
attribute contains an expression that will be provided by theHello
managed bean.The web page connects to the
Hello
managed bean through the Expression Language (EL) value expression#{hello.name}
, which retrieves the value of thename
property from the managed bean. Note the use ofhello
to reference the managed beanHello
. If no name is specified in the@Named
annotation of the managed bean, the managed bean is always accessed with the first letter of the class name in lowercase.The Submit
commandButton
element specifies the action asresponse
, meaning that when the button is clicked, theresponse.xhtml
page is displayed. -
Double-click the
response.xhtml
file to view it.The response page appears. Even simpler than the greeting page, the response page contains a graphic image, a header that displays the expression provided by the managed bean, and a single button whose
action
element transfers you back to theindex.xhtml
page:<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html lang="en" xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://xmlns.jcp.org/jsf/html"> <h:head> <title>Facelets Hello Response</title> </h:head> <h:body> <h:form> <h:graphicImage url="#{resource['images:duke.waving.gif']}" alt="Duke waving his hand"/> <h2>Hello, #{hello.name}!</h2> <p></p> <h:commandButton id="back" value="Back" action="index" /> </h:form> </h:body> </html>
-
Expand the Source Packages node, then the
ee.jakarta.tutorial.hello1
node. -
Double-click the
Hello.java
file to view it.The
Hello
class, called a managed bean class, provides getter and setter methods for thename
property used in the Facelets page expressions. By default, the expression language refers to the class name, with the first letter in lowercase (hello.name
).package ee.jakarta.tutorial.hello1; import jakarta.enterprise.context.RequestScoped; import jakarta.inject.Named; @Named @RequestScoped public class Hello { private String name; public Hello() { } public String getName() { return name; } public void setName(String user_name) { this.name = user_name; } }
If you use the default name for the bean class, you can specify
@Model
as the annotation instead of having to specify both@Named
and@RequestScoped
. The@Model
annotation is called a stereotype, a term for an annotation that encapsulates other annotations. It is described later in Using Stereotypes in CDI Applications. Some examples will use@Model
where it is appropriate. -
Under the Web Pages node, expand the WEB-INF node and double-click the
web.xml
file to view it.The
web.xml
file contains several elements that are required for a Facelets application. All of the following are created automatically when you use NetBeans IDE to create an application.-
A context parameter specifying the project stage:
<context-param> <param-name>javax.faces.PROJECT_STAGE</param-name> <param-value>Development</param-value> </context-param>
A context parameter provides configuration information needed by a web application. An application can define its own context parameters. In addition, Jakarta Server Faces technology and Jakarta Servlet technology define context parameters that an application can use.
-
A
servlet
element and itsservlet-mapping
element specifying theFacesServlet
. All files with the.xhtml
suffix will be matched:<servlet> <servlet-name>Faces Servlet</servlet-name> <servlet-class>javax.faces.webapp.FacesServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>Faces Servlet</servlet-name> <url-pattern>*.xhtml</url-pattern> </servlet-mapping>
-
A
welcome-file-list
element specifying the location of the landing page:<welcome-file-list> <welcome-file>index.xhtml</welcome-file> </welcome-file-list>
-
Introduction to Scopes
In the Hello.java
class, the annotations javax.inject.Named
and
javax.enterprise.context.RequestScoped
identify the class as a managed
bean using request scope. Scope defines how application data persists
and is shared.
The most commonly used scopes in Jakarta Server Faces applications are the following:
-
Request (
@RequestScoped
): Request scope persists during a single HTTP request in a web application. In an application likehello1
, in which the application consists of a single request and response, the bean uses request scope. -
Session (
@SessionScoped
): Session scope persists across multiple HTTP requests in a web application. When an application consists of multiple requests and responses where data needs to be maintained, beans use session scope. -
Application (
@ApplicationScoped
): Application scope persists across all users' interactions with a web application.
For more information on scopes in Jakarta Server Faces technology, see Using Managed Bean Scopes.
4.1.3.2. Packaging and Deploying the hello1 Web Module
A web module must be packaged into a WAR in certain deployment scenarios
and whenever you want to distribute the web module. You can package a
web module into a WAR file by using Maven or by using the IDE tool of
your choice. This tutorial shows you how to use NetBeans IDE or Maven to
build, package, and deploy the hello1
sample application.
You can deploy a WAR file to GlassFish Server by:
-
Using NetBeans IDE
-
Using the
asadmin
command -
Using the Administration Console
-
Copying the WAR file into the
domain-dir/autodeploy/
directory
Throughout the tutorial, you will use NetBeans IDE or Maven for packaging and deploying.
To Build and Package the hello1 Web Module Using NetBeans IDE
To build and package the hello1
web module using NetBeans IDE:
-
Start GlassFish Server as described in To Start GlassFish Server Using NetBeans IDE, if you have not already done so.
-
From the File menu, choose Open Project.
-
In the Open Project dialog box, navigate to:
tut-install/examples/web/jsf
-
Select the
hello1
folder. -
Click Open Project.
-
In the Projects tab, right-click the
hello1
project and select Build. This command deploys the project to the server.
To Build and Package the hello1 Web Module Using Maven
To build and package the hello1
web module using Maven:
-
Start GlassFish Server as described in To Start GlassFish Server Using the Command Line, if you have not already done so.
-
In a terminal window, go to:
tut-install/examples/web/jsf/hello1/
-
Enter the following command:
mvn install
This command spawns any necessary compilations and creates the WAR file in
tut-install/examples/web/jsf/hello1/target/
. It then deploys the project to the server.
4.1.3.3. Viewing Deployed Web Modules
GlassFish Server provides two ways to view the deployed web modules: the
Administration Console and the asadmin
command. You can also use
NetBeans IDE to view deployed modules.
To View Deployed Web Modules Using the Administration Console
To view deployed web modules using the Administration Console:
-
Open the URL
http://localhost:4848/
in a browser. -
Select the Applications node.
The deployed web modules appear in the Deployed Applications table.
4.1.3.4. Running the Deployed hello1 Web Module
Now that the web module is deployed, you can view it by opening the
application in a web browser. By default, the application is deployed to
host localhost
on port 8080. The context root of the web application
is hello1
.
To run the deployed hello1
web module:
-
Open a web browser.
-
Enter the following URL:
http://localhost:8080/hello1/
-
In the field, enter your name and click Submit.
The response page displays the name you submitted. Click Back to try again.
Dynamic Reloading of Deployed Modules
If dynamic reloading is enabled, you do not have to redeploy an
application or module when you change its code or deployment
descriptors. All you have to do is copy the changed pages or class files
into the deployment directory for the application or module. The
deployment directory for a web module named context-root is
domain-dir/applications/context-root
. The server checks for changes
periodically and redeploys the application, automatically and
dynamically, with the changes.
This capability is useful in a development environment because it allows code changes to be tested quickly. Dynamic reloading is not recommended for a production environment, however, because it may degrade performance. In addition, whenever a reload takes place, the sessions at that time become invalid, and the client must restart the session.
In GlassFish Server, dynamic reloading is enabled by default.
4.1.3.5. Undeploying the hello1 Web Module
You can undeploy web modules and other types of enterprise applications by using either NetBeans IDE or Maven.
To Undeploy the hello1 Web Module Using NetBeans IDE
To undeploy the hello1
web module using NetBeans IDE:
-
In the Services tab, expand the Servers node, then expand the GlassFish Server node.
-
Expand the Applications node.
-
Right-click the
hello1
module and select Undeploy. -
To delete the class files and other build artifacts, go back to the Projects tab, right-click the project, and select Clean.
4.1.4. A Web Module That Uses Jakarta Servlet Technology: The hello2 Example
The hello2
application is a web module that uses Jakarta Servlet
technology to display a greeting and response. You can use a text editor
to view the application files, or you can use NetBeans IDE.
The source code for this application is in the
tut-install/examples/web/servlet/hello2/
directory.
4.1.4.1. Mapping URLs to Web Components
When it receives a request, the web container must determine which web component should handle the request. The web container does so by mapping the URL path contained in the request to a web application and a web component. A URL path contains the context root and, optionally, a URL pattern:
http://host:port/context-root[/url-pattern]
You set the URL pattern for a servlet by using the @WebServlet
annotation in the servlet source file. For example, the
GreetingServlet.java
file in the hello2
application contains the
following annotation, specifying the URL pattern as /greeting
:
@WebServlet("/greeting")
public class GreetingServlet extends HttpServlet {
...
This annotation indicates that the URL pattern /greeting
follows the
context root. Therefore, when the servlet is deployed locally, it is
accessed with the following URL:
http://localhost:8080/hello2/greeting
To access the servlet by using only the context root, specify "/"
as
the URL pattern.
4.1.4.2. Examining the hello2 Web Module
The hello2
application behaves almost identically to the hello1
application, but it is implemented using Jakarta Servlet technology instead
of Jakarta Server Faces technology. You can use a text editor to view the
application files, or you can use NetBeans IDE.
To View the hello2 Web Module Using NetBeans IDE
To view the hello2
web module using NetBeans IDE:
-
From the File menu, choose Open Project.
-
In the Open Project dialog box, navigate to:
tut-install/examples/web/servlet
-
Select the
hello2
folder and click Open Project. -
Expand the Source Packages node, then expand the
ee.jakarta.tutorial.hello2
node. -
Double-click the
GreetingServlet.java
file to view it.This servlet overrides the
doGet
method, implementing theGET
method of HTTP. The servlet displays a simple HTML greeting form whose Submit button, like that ofhello1
, specifies a response page for its action. The following excerpt begins with the@WebServlet
annotation, which specifies the URL pattern relative to the context root:@WebServlet("/greeting") public class GreetingServlet extends HttpServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html"); response.setBufferSize(8192); try (PrintWriter out = response.getWriter()) { out.println("<html lang=\"en\">" + "<head><title>Servlet Hello</title></head>"); // then write the data of the response out.println("<body bgcolor=\"#ffffff\">" + "<img src=\"duke.waving.gif\" " + "alt=\"Duke waving his hand\">" + "<form method=\"get\">" + "<h2>Hello, my name is Duke. What's yours?</h2>" + "<input title=\"My name is: \"type=\"text\" " + "name=\"username\" size=\"25\">" + "<p></p>" + "<input type=\"submit\" value=\"Submit\">" + "<input type=\"reset\" value=\"Reset\">" + "</form>"); String username = request.getParameter("username"); if (username != null && username.length()> 0) { RequestDispatcher dispatcher = getServletContext().getRequestDispatcher("/response"); if (dispatcher != null) { dispatcher.include(request, response); } } out.println("</body></html>"); } } ...
-
Double-click the
ResponseServlet.java
file to view it.This servlet also overrides the
doGet
method, displaying only the response. The following excerpt begins with the@WebServlet
annotation, which specifies the URL pattern relative to the context root:@WebServlet("/response") public class ResponseServlet extends HttpServlet { @Override public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { try (PrintWriter out = response.getWriter()) { // then write the data of the response String username = request.getParameter("username"); if (username != null && username.length()> 0) { out.println("<h2>Hello, " + username + "!</h2>"); } } } ...
4.1.4.3. Running the hello2 Example
You can use either NetBeans IDE or Maven to build, package, deploy, and
run the hello2
example.
To Run the hello2 Example Using NetBeans IDE
To run the hello2
example using NetBeans IDE:
-
Start GlassFish Server as described in To Start GlassFish Server Using NetBeans IDE, if you have not already done so.
-
From the File menu, choose Open Project.
-
In the Open Project dialog box, navigate to:
tut-install/examples/web/servlet
-
Select the
hello2
folder. -
Click Open Project.
-
In the Projects tab, right-click the
hello2
project and select Build to package and deploy the project. -
In a web browser, open the following URL:
http://localhost:8080/hello2/greeting
The URL specifies the context root, followed by the URL pattern.
The application looks much like the
hello1
application. The major difference is that after you click Submit the response appears below the greeting, not on a separate page.
To Run the hello2 Example Using Maven
To run the hello2
example using Maven:
-
Start GlassFish Server as described in To Start GlassFish Server Using the Command Line, if you have not already done so.
-
In a terminal window, go to:
tut-install/examples/web/servlet/hello2/
-
Enter the following command:
mvn install
This target builds the WAR file, copies it to the
tut-install/examples/web/hello2/target/
directory, and deploys it. -
In a web browser, open the following URL:
http://localhost:8080/hello2/greeting
The URL specifies the context root, followed by the URL pattern.
The application looks much like the
hello1
application. The major difference is that after you click Submit the response appears below the greeting, not on a separate page.
4.1.5. Configuring Web Applications
This section describes the following tasks involved with configuring web applications:
-
Setting context parameters
-
Declaring welcome files
-
Mapping errors to error screens
-
Declaring resource references
4.1.5.1. Setting Context Parameters
The web components in a web module share an object that represents their application context. You can pass context parameters to the context, or you can pass initialization parameters to a servlet. Context parameters are available to the entire application. For information on initialization parameters, see Creating and Initializing a Servlet.
To Add a Context Parameter Using NetBeans IDE
These steps apply generally to web applications but do not apply specifically to the examples in this chapter.
To add a context parameter using NetBeans IDE:
-
Open the project.
-
Expand the project’s node in the Projects tree.
-
Expand the Web Pages node and then the WEB-INF node.
-
Double-click
web.xml
.If the project does not have a
web.xml
file, create one by following the steps in To Create a web.xml File Using NetBeans IDE. -
Click General at the top of the editor window.
-
Expand the Context Parameters node.
-
Click Add.
-
In the Add Context Parameter dialog box, in the Parameter Name field, enter the name that specifies the context object.
-
In the Parameter Value field, enter the parameter to pass to the context object.
-
Click OK.
To Create a web.xml File Using NetBeans IDE
To create a web.xml
file using NetBeans IDE:
-
From the File menu, choose New File.
-
In the New File wizard, select the Web category, then select Standard Deployment Descriptor under File Types.
-
Click Next.
-
Click Finish.
A basic
web.xml
file appears inweb/WEB-INF/
.
4.1.5.2. Declaring Welcome Files
The welcome files mechanism allows you to specify a list of files that
the web container can append to a request for a URL (called a valid
partial request) that is not mapped to a web component. For example,
suppose that you define a welcome file welcome.html
. When a client
requests a URL such as host:port/webapp/directory
, where directory
is not mapped to a servlet or XHTML page, the file
host:port/webapp/directory/`welcome.html
is returned to the
client.
If a web container receives a valid partial request, the web container examines the welcome file list, appends to the partial request each welcome file in the order specified, and checks whether a static resource or servlet in the WAR is mapped to that request URL. The web container then sends the request to the first resource that matches in the WAR.
If no welcome file is specified, GlassFish Server will use a file named
index.html
as the default welcome file. If there is no welcome file
and no file named index.html
, GlassFish Server returns a directory
listing.
You specify welcome files in the web.xml
file. The welcome file
specification for the hello1
example looks like this:
<welcome-file-list>
<welcome-file>index.xhtml</welcome-file>
</welcome-file-list>
A specified welcome file must not have a leading or trailing slash
(/
).
The hello2
example does not specify a welcome file, because the URL
request is mapped to the GreetingServlet
web component through the URL
pattern /greeting
.
4.1.5.3. Mapping Errors to Error Screens
When an error occurs during execution of a web application, you can have the application display a specific error screen according to the type of error. In particular, you can specify a mapping between the status code returned in an HTTP response or a Java programming language exception returned by any web component and any type of error screen.
You can have multiple error-page
elements in your deployment
descriptor. Each element identifies a different error that causes an
error page to open. This error page can be the same for any number of
error-page
elements.
To Set Up Error Mapping Using NetBeans IDE
These steps apply generally to web applications but do not apply specifically to the examples in this chapter.
To set up error mapping using NetBeans IDE:
-
Open the project.
-
Expand the project’s node in the Projects tab.
-
Expand the Web Pages node and then the WEB-INF node.
-
Double-click
web.xml
.If the project does not have a
web.xml
file, create one by following the steps in To Create a web.xml File Using NetBeans IDE. -
Click Pages at the top of the editor window.
-
Expand the Error Pages node.
-
Click Add.
-
In the Add Error Page dialog box, click Browse to locate the page that you want to act as the error page.
-
Specify either an error code or an exception type.
-
To specify an error code, in the Error Code field enter the HTTP status code that will cause the error page to be opened, or leave the field blank to include all error codes.
-
To specify an exception type, in the Exception Type field enter the exception that will cause the error page to load. To specify all throwable errors and exceptions, enter
java.lang.Throwable
.
-
-
Click OK.
4.1.5.4. Declaring Resource References
If your web component uses such objects as enterprise beans, data sources, or web services, you use Jakarta EE annotations to inject these resources into your application. Annotations eliminate a lot of the boilerplate lookup code and configuration elements that previous versions of Jakarta EE required.
Although resource injection using annotations can be more convenient for the developer, there are some restrictions on using it in web applications. First, you can inject resources only into container-managed objects, because a container must have control over the creation of a component so that it can perform the injection into a component. As a result, you cannot inject resources into such objects as simple JavaBeans components. However, managed beans are managed by the container; therefore, they can accept resource injections.
Components that can accept resource injections are listed in Table 6-1.
This section explains how to use a couple of the annotations supported by a web container to inject resources. Chapter 41, "Running the Persistence Examples", explains how web applications use annotations supported by Jakarta Persistence. Chapter 51, "Getting Started Securing Web Applications", explains how to use annotations to specify information about securing web applications. See Chapter 55, "Resource Adapters and Contracts", for more information on resources.
Table 6-1 Web Components That Accept Resource Injections
Component |
Interface/Class |
Servlets |
|
Servlet filters |
|
Event listeners |
|
Managed beans |
Plain Old Java Objects |
Declaring a Reference to a Resource
The @Resource
annotation is used to declare a reference to a resource,
such as a data source, an enterprise bean, or an environment entry.
The @Resource
annotation is specified on a class, a method, or a
field. The container is responsible for injecting references to
resources declared by the @Resource
annotation and mapping it to the
proper JNDI resources.
In the following example, the @Resource
annotation is used to inject a
data source into a component that needs to make a connection to the data
source, as is done when using JDBC technology to access a relational
database:
@Resource javax.sql.DataSource catalogDS;
public getProductsByCategory() {
// get a connection and execute the query
Connection conn = catalogDS.getConnection();
...
}
The container injects this data source prior to the component’s being
made available to the application. The data source JNDI mapping is
inferred from the field name, catalogDS
, and the type,
javax.sql.DataSource
.
If you have multiple resources that you need to inject into one
component, you need to use the @Resources
annotation to contain them,
as shown by the following example:
@Resources ({
@Resource(name="myDB" type=javax.sql.DataSource.class),
@Resource(name="myMQ" type=javax.jms.ConnectionFactory.class)
})
The web application examples in this tutorial use Jakarta Persistence
to access relational databases. This API does not require you to
explicitly create a connection to a data source. Therefore, the examples
do not use the @Resource
annotation to inject a data source. However,
this API supports the @PersistenceUnit
and @PersistenceContext
annotations for injecting EntityManagerFactory
and EntityManager
instances, respectively.
Chapter 41, "Running the
Persistence Examples" describes these annotations and the use of the
Jakarta Persistence in web applications.
Declaring a Reference to a Web Service
The @WebServiceRef
annotation provides a reference to a web service.
The following example shows uses the @WebServiceRef
annotation to
declare a reference to a web service. WebServiceRef
uses the
wsdlLocation
element to specify the URI of the deployed service’s WSDL
file:
...
import jakarta.xml.ws.WebServiceRef;
...
public class ResponseServlet extends HTTPServlet {
@WebServiceRef(wsdlLocation="http://localhost:8080/helloservice/hello?wsdl")
static HelloService service;
4.2. Jakarta Server Faces Technology
Jakarta Server Faces technology is a server-side component framework for building Java technology–based web applications.
4.2.1. Introduction to Jakarta Server Faces Technology
Jakarta Server Faces technology consists of the following:
-
An API for representing components and managing their state; handling events, server-side validation, and data conversion; defining page navigation; supporting internationalization and accessibility; and providing extensibility for all these features
-
Tag libraries for adding components to web pages and for connecting components to server-side objects
Jakarta Server Faces technology provides a well-defined programming model and various tag libraries. The tag libraries contain tag handlers that implement the component tags. These features significantly ease the burden of building and maintaining web applications with server-side user interfaces (UIs). With minimal effort, you can complete the following tasks.
-
Create a web page.
-
Drop components onto a web page by adding component tags.
-
Bind components on a page to server-side data.
-
Wire component-generated events to server-side application code.
-
Save and restore application state beyond the life of server requests.
-
Reuse and extend components through customization.
This chapter provides an overview of Jakarta Server Faces technology. After explaining what a Jakarta Server Faces application is and reviewing some of the primary benefits of using Jakarta Server Faces technology, this chapter describes the process of creating a simple Jakarta Server Faces application. This chapter also introduces the Jakarta Server Faces lifecycle by describing the example Jakarta Server Faces application and its progression through the lifecycle stages.
4.2.2. What Is a Jakarta Server Faces Application?
The functionality provided by a Jakarta Server Faces application is similar to that of any other Java web application. A typical Jakarta Server Faces application includes the following parts.
-
A set of web pages in which components are laid out.
-
A set of tags to add components to the web page.
-
A set of managed beans, which are lightweight, container-managed objects (POJOs). In a Jakarta Server Faces application, managed beans serve as backing beans, which define properties and functions for UI components on a page.
-
A web deployment descriptor (
web.xml
file). -
Optionally, one or more application configuration resource files, such as a
faces-config.xml
file, which can be used to define page navigation rules and configure beans and other custom objects, such as custom components. -
Optionally, a set of custom objects, which can include custom components, validators, converters, or listeners, created by the application developer.
-
Optionally, a set of custom tags for representing custom objects on the page.
Figure 7-1 shows the interaction between client and server in a typical Jakarta Server Faces application. In response to a client request, a web page is rendered by the web container that implements Jakarta Server Faces technology.
The web page, myfacelet.xhtml
, is built using Jakarta Server Faces
component tags. Component tags are used to add components to the view
(represented by myView
in the diagram), which is the server-side
representation of the page. In addition to components, the web page can
also reference objects, such as the following:
-
Any event listeners, validators, and converters that are registered on the components
-
The JavaBeans components that capture the data and process the application-specific functionality of the components
On request from the client, the view is rendered as a response. Rendering is the process whereby, based on the server-side view, the web container generates output, such as HTML or XHTML, that can be read by the client, such as a browser.
4.2.3. Jakarta Server Faces Technology Benefits
One of the greatest advantages of Jakarta Server Faces technology is that it offers a clean separation between behavior and presentation for web applications. A Jakarta Server Faces application can map HTTP requests to component-specific event handling and manage components as stateful objects on the server. Jakarta Server Faces technology allows you to build web applications that implement the finer-grained separation of behavior and presentation that is traditionally offered by client-side UI architectures.
The separation of logic from presentation also allows each member of a web application development team to focus on a single piece of the development process and provides a simple programming model to link the pieces. For example, page authors with no programming expertise can use Jakarta Server Faces technology tags in a web page to link to server-side objects without writing any scripts.
Another important goal of Jakarta Server Faces technology is to leverage familiar component and web-tier concepts without limiting you to a particular scripting technology or markup language. Jakarta Server Faces technology APIs are layered directly on top of the Servlet API, as shown in Figure 7-2.
This layering of APIs enables several important application use cases, such as using different presentation technologies, creating your own custom components directly from the component classes, and generating output for various client devices.
Facelets technology, available as part of Jakarta Server Faces technology, is the preferred presentation technology for building Jakarta Server Faces technology–based web applications. For more information on Facelets technology features, see Chapter 8, "Introduction to Facelets".
Facelets technology offers several advantages.
-
Code can be reused and extended for components through the templating and composite component features.
-
You can use annotations to automatically register the managed bean as a resource available for Jakarta Server Faces applications. In addition, implicit navigation rules allow developers to quickly configure page navigation (see Navigation Model for details). These features reduce the manual configuration process for applications.
-
Most important, Jakarta Server Faces technology provides a rich architecture for managing component state, processing component data, validating user input, and handling events.
4.2.4. A Simple Jakarta Server Faces Application
Jakarta Server Faces technology provides an easy and user-friendly process for creating web applications. Developing a simple Jakarta Server Faces application typically requires the following tasks, which have already been described in A Web Module That Uses Jakarta Server Faces Technology: The hello1 Example:
-
Creating web pages using component tags
-
Developing managed beans
-
Mapping the
FacesServlet
instance
The hello1
example includes a managed bean and two Facelets web pages.
When accessed by a client, the first web page asks the user for his or
her name, and the second page responds by providing a greeting.
For details on Facelets technology, see Chapter 8, "Introduction to Facelets". For details on using EL expressions, see Chapter 9, "Expression Language". For details on the Jakarta Server Faces programming model and building web pages using Jakarta Server Faces technology, see Chapter 10, "Using Jakarta Server Faces Technology in Web Pages".
Every web application has a lifecycle. Common tasks, such as handling incoming requests, decoding parameters, modifying and saving state, and rendering web pages to the browser, are all performed during a web application lifecycle. Some web application frameworks hide the details of the lifecycle from you, whereas others require you to manage them manually.
By default, Jakarta Server Faces automatically handles most of the lifecycle actions for you. However, it also exposes the various stages of the request lifecycle so that you can modify or perform different actions if your application requirements warrant it.
The lifecycle of a Jakarta Server Faces application starts and ends with the following activity: The client makes a request for the web page, and the server responds with the page. The lifecycle consists of two main phases: Execute and Render.
During the Execute phase, several actions can take place.
-
The application view is built or restored.
-
The request parameter values are applied.
-
Conversions and validations are performed for component values.
-
Managed beans are updated with component values.
-
Application logic is invoked.
For a first (initial) request, only the view is built. For subsequent (postback) requests, some or all of the other actions can take place.
In the Render phase, the requested view is rendered as a response to the client. Rendering is typically the process of generating output, such as HTML or XHTML, that can be read by the client, usually a browser.
The following short description of the example Jakarta Server Faces application passing through its lifecycle summarizes the activity that takes place behind the scenes.
The hello1
example application goes through the following stages when
it is deployed on GlassFish Server.
-
When the
hello1
application is built and deployed on GlassFish Server, the application is in an uninitiated state. -
When a client makes an initial request for the
index.xhtml
web page, thehello1
Facelets application is compiled. -
The compiled Facelets application is executed, and a new component tree is constructed for the
hello1
application and placed in aFacesContext
. -
The component tree is populated with the component and the managed bean property associated with it, represented by the EL expression
hello.name
. -
A new view is built, based on the component tree.
-
The view is rendered to the requesting client as a response.
-
The component tree is destroyed automatically.
-
On subsequent (postback) requests, the component tree is rebuilt, and the saved state is applied.
For full details on the lifecycle, see The Lifecycle of a Jakarta Server Faces Application.
4.2.5. User Interface Component Model
In addition to the lifecycle description, an overview of Jakarta Server Faces architecture provides better understanding of the technology.
Jakarta Server Faces components are the building blocks of a Jakarta Server Faces view. A component can be a user interface (UI) component or a non-UI component.
Jakarta Server Faces UI components are configurable, reusable elements that compose the user interfaces of Jakarta Server Faces applications. A component can be simple, such as a button, or can be compound, such as a table composed of multiple components.
Jakarta Server Faces technology provides a rich, flexible component architecture that includes the following:
-
A set of
javax.faces.component.UIComponent
classes for specifying the state and behavior of UI components -
A rendering model that defines how to render the components in various ways
-
A conversion model that defines how to register data converters onto a component
-
An event and listener model that defines how to handle component events
-
A validation model that defines how to register validators onto a component
This section briefly describes each of these pieces of the component architecture.
4.2.5.1. User Interface Component Classes
Jakarta Server Faces technology provides a set of UI component classes and associated behavioral interfaces that specify all the UI component functionality, such as holding component state, maintaining a reference to objects, and driving event handling and rendering for a set of standard components.
The component classes are completely extensible, allowing component writers to create their own custom components. See Chapter 15, "Creating Custom UI Components and Other Custom Objects" for more information.
The abstract base class for all components is
javax.faces.component.UIComponent
. Jakarta Server Faces UI component
classes extend the UIComponentBase
class (a subclass of
UIComponent
), which defines the default state and behavior of a
component. The following set of component classes is included with
Jakarta Server Faces technology.
-
UIColumn
: Represents a single column of data in aUIData
component. -
UICommand
: Represents a control that fires actions when activated. -
UIData
: Represents a data binding to a collection of data represented by ajavax.faces.model.DataModel
instance. -
UIForm
: Represents an input form to be presented to the user. Its child components represent (among other things) the input fields to be included when the form is submitted. This component is analogous to theform
tag in HTML. -
UIGraphic
: Displays an image. -
UIInput
: Takes data input from a user. This class is a subclass ofUIOutput
. -
UIMessage
: Displays a localized error message. -
UIMessages
: Displays a set of localized error messages. -
UIOutcomeTarget
: Displays a link in the form of a link or a button. -
UIOutput
: Displays data output on a page. -
UIPanel
: Manages the layout of its child components. -
UIParameter
: Represents substitution parameters. -
UISelectBoolean
: Allows a user to set aboolean
value on a control by selecting or deselecting it. This class is a subclass of theUIInput
class. -
UISelectItem
: Represents a single item in a set of items. -
UISelectItems
: Represents an entire set of items. -
UISelectMany
: Allows a user to select multiple items from a group of items. This class is a subclass of theUIInput
class. -
UISelectOne
: Allows a user to select one item from a group of items. This class is a subclass of theUIInput
class. -
UIViewParameter
: Represents the query parameters in a request. This class is a subclass of theUIInput
class. -
UIViewRoot
: Represents the root of the component tree.
In addition to extending UIComponentBase
, the component classes also
implement one or more behavioral interfaces, each of which defines
certain behavior for a set of components whose classes implement the
interface.
These behavioral interfaces, all defined in the javax.faces.component
package unless otherwise stated, are as follows.
-
ActionSource
: Indicates that the component can fire an action event. This interface is intended for use with components based on Jakarta Server Faces technology 1.1_01 and earlier versions. This interface is deprecated in Jakarta Server Faces 2. -
ActionSource2
: ExtendsActionSource
and therefore provides the same functionality. However, it allows components to use the Expression Language (EL) when they are referencing methods that handle action events. -
EditableValueHolder
: ExtendsValueHolder
and specifies additional features for editable components, such as validation and emitting value-change events. -
NamingContainer
: Mandates that each component rooted at this component have a unique ID. -
StateHolder
: Denotes that a component has state that must be saved between requests. -
ValueHolder
: Indicates that the component maintains a local value as well as the option of accessing data in the model tier. -
javax.faces.event.SystemEventListenerHolder
: Maintains a list ofjavax.faces.event.SystemEventListener
instances for each type ofjavax.faces.event.SystemEvent
defined by that class. -
javax.faces.component.behavior.ClientBehaviorHolder
: Adds the ability to attachjavax.faces.component.behavior.ClientBehavior
instances, such as a reusable script.
UICommand
implements ActionSource2
and StateHolder
. UIOutput
and
component classes that extend UIOutput
implement StateHolder
and
ValueHolder
. UIInput
and component classes that extend UIInput
implement EditableValueHolder
, StateHolder
, and ValueHolder
.
UIComponentBase
implements StateHolder
.
Only component writers will need to use the component classes and
behavioral interfaces directly. Page authors and application developers
will use a standard component by including a tag that represents it on a
page. Most of the components can be rendered in different ways on a
page. For example, a UICommand
component can be rendered as a button
or a link.
The next section explains how the rendering model works and how page authors can choose to render the components by selecting the appropriate tags.
4.2.5.2. Component Rendering Model
The Jakarta Server Faces component architecture is designed such that the functionality of the components is defined by the component classes, whereas the component rendering can be defined by a separate renderer class. This design has several benefits, including the following.
-
Component writers can define the behavior of a component once but create multiple renderers, each of which defines a different way to render the component to the same client or to different clients.
-
Page authors and application developers can change the appearance of a component on the page by selecting the tag that represents the appropriate combination of component and renderer.
A render kit defines how component classes map to component tags that are appropriate for a particular client. The Jakarta Server Faces implementation includes a standard HTML render kit for rendering to an HTML client.
The render kit defines a set of javax.faces.render.Renderer
classes
for each component that it supports. Each Renderer
class defines a
different way to render the particular component to the output defined
by the render kit. For example, a UISelectOne
component has three
different renderers. One of them renders the component as a group of
options. Another renders the component as a combo box. The third one
renders the component as a list box. Similarly, a UICommand
component
can be rendered as a button or a link, using the h:commandButton
or
h:commandLink
tag. The command
part of each tag corresponds to the
UICommand
class, specifying the functionality, which is to fire an
action. The Button
or Link
part of each tag corresponds to a
separate Renderer
class that defines how the component appears on the
page.
Each custom tag defined in the standard HTML render kit is composed of
the component functionality (defined in the UIComponent
class) and the
rendering attributes (defined by the Renderer
class).
The section Adding Components to a Page Using HTML Tag Library Tags lists all supported component tags and illustrates how to use the tags in an example.
The Jakarta Server Faces implementation provides a custom tag library for rendering components in HTML.
4.2.5.3. Conversion Model
A Jakarta Server Faces application can optionally associate a component with server-side object data. This object is a JavaBeans component, such as a managed bean. An application gets and sets the object data for a component by calling the appropriate object properties for that component.
When a component is bound to an object, the application has two views of the component’s data.
-
The model view, in which data is represented as data types, such as
int
orlong
. -
The presentation view, in which data is represented in a manner that can be read or modified by the user. For example, a
java.util.Date
might be represented as a text string in the formatmm/dd/yy
or as a set of three text strings.
The Jakarta Server Faces implementation automatically converts component
data between these two views when the bean property associated with the
component is of one of the types supported by the component’s data. For
example, if a UISelectBoolean
component is associated with a bean
property of type java.lang.Boolean
, the Jakarta Server Faces
implementation will automatically convert the component’s data from
String
to Boolean
. In addition, some component data must be bound to
properties of a particular type. For example, a UISelectBoolean
component must be bound to a property of type boolean
or
java.lang.Boolean
.
Sometimes you might want to convert a component’s data to a type other
than a standard type, or you might want to convert the format of the
data. To facilitate this, Jakarta Server Faces technology allows you to
register a javax.faces.convert.Converter
implementation on UIOutput
components and components whose classes subclass UIOutput
. If you
register the Converter
implementation on a component, the Converter
implementation converts the component’s data between the two views.
You can either use the standard converters supplied with the Jakarta Server Faces implementation or create your own custom converter. Custom converter creation is covered in Chapter 15, "Creating Custom UI Components and Other Custom Objects".
4.2.5.4. Event and Listener Model
The Jakarta Server Faces event and listener model is similar to the JavaBeans event model in that it has strongly typed event classes and listener interfaces that an application can use to handle events generated by components.
The Jakarta Server Faces specification defines three types of events: application events, system events, and data-model events.
Application events are tied to a particular application and are
generated by a UIComponent
. They represent the standard events
available in previous versions of Jakarta Server Faces technology.
An event object identifies the component that generated the event and stores information about the event. To be notified of an event, an application must provide an implementation of the listener class and must register it on the component that generates the event. When the user activates a component, such as by clicking a button, an event is fired. This causes the Jakarta Server Faces implementation to invoke the listener method that processes the event.
Jakarta Server Faces supports two kinds of application events: action events and value-change events.
An action event (class javax.faces.event.ActionEvent
) occurs when the
user activates a component that implements ActionSource
. These
components include buttons and links.
A value-change event (class javax.faces.event.ValueChangeEvent
) occurs
when the user changes the value of a component represented by UIInput
or one of its subclasses. An example is selecting a check box, an action
that results in the component’s value changing to true
. The component
types that can generate these types of events are the UIInput
,
UISelectOne
, UISelectMany
, and UISelectBoolean
components.
Value-change events are fired only if no validation errors are detected.
Depending on the value of the immediate
property (see
The immediate Attribute) of the component
emitting the event, action events can be processed during the Invoke
Application phase or the Apply Request Values phase, and value-change
events can be processed during the Process Validations phase or the
Apply Request Values phase.
System events are generated by an Object
rather than a UIComponent
.
They are generated during the execution of an application at predefined
times. They are applicable to the entire application rather than to a
specific component.
A data-model event occurs when a new row of a UIData
component is
selected.
There are two ways to cause your application to react to action events or value-change events that are emitted by a standard component:
-
Implement an event listener class to handle the event, and register the listener on the component by nesting either an
f:valueChangeListener
tag or anf:actionListener
tag inside the component tag. -
Implement a method of a managed bean to handle the event, and refer to the method with a method expression from the appropriate attribute of the component’s tag.
See Implementing an Event Listener for information on how to implement an event listener. See Registering Listeners on Components for information on how to register the listener on a component.
See Writing a Method to Handle an Action Event and Writing a Method to Handle a Value-Change Event for information on how to implement managed bean methods that handle these events.
See Referencing a Managed Bean Method for information on how to refer to the managed bean method from the component tag.
When emitting events from custom components, you must implement the appropriate event class and manually queue the event on the component in addition to implementing an event listener class or a managed bean method that handles the event. Handling Events for Custom Components explains how to do this.
4.2.5.5. Validation Model
Jakarta Server Faces technology supports a mechanism for validating the local data of editable components (such as text fields). This validation occurs before the corresponding model data is updated to match the local value.
Like the conversion model, the validation model defines a set of
standard classes for performing common data validation checks. The
Jakarta Server Faces core tag library also defines a set of tags that
correspond to the standard javax.faces.validator.Validator
implementations. See Using the Standard
Validators for a list of all the standard validation classes and
corresponding tags.
Most of the tags have a set of attributes for configuring the validator’s properties, such as the minimum and maximum allowable values for the component’s data. The page author registers the validator on a component by nesting the validator’s tag within the component’s tag.
In addition to validators that are registered on the component, you can
declare a default validator that is registered on all UIInput
components in the application. For more information on default
validators, see Using Default
Validators.
The validation model also allows you to create your own custom validator and corresponding tag to perform custom validation. The validation model provides two ways to implement custom validation.
-
Implement a
Validator
interface that performs the validation. -
Implement a managed bean method that performs the validation.
If you are implementing a Validator
interface, you must also do the
following.
-
Register the
Validator
implementation with the application. -
Create a custom tag or use an
f:validator
tag to register the validator on the component.
In the previously described standard validation model, the validator is defined for each input component on a page. The Bean Validation model allows the validator to be applied to all fields in a page. See Chapter 23, "Introduction to Bean Validation" and Chapter 24, "Bean Validation: Advanced Topics" for more information on Bean Validation.
4.2.6. Navigation Model
The Jakarta Server Faces navigation model makes it easy to define page navigation and to handle any additional processing that is needed to choose the sequence in which pages are loaded.
In Jakarta Server Faces technology, navigation is a set of rules for choosing the next page or view to be displayed after an application action, such as when a button or link is clicked.
Navigation can be implicit or user-defined. Implicit navigation comes into play when user-defined navigation rules are not configured in the application configuration resource files.
When you add a component such as a commandButton
to a Facelets page,
and assign another page as the value for its action
property, the
default navigation handler will try to match a suitable page within the
application implicitly. In the following example, the default navigation
handler will try to locate a page named response.xhtml
within the
application and navigate to it:
<h:commandButton value="submit" action="response">
User-defined navigation rules are declared in zero or more application
configuration resource files, such as faces-config.xml
, by using a set
of XML elements. The default structure of a navigation rule is as
follows:
<navigation-rule>
<description></description
<from-view-id></from-view-id>
<navigation-case>
<from-action></from-action>
<from-outcome></from-outcome>
<if></if>
<to-view-id></to-view-id>
</navigation-case>
</navigation-rule>
User-defined navigation is handled as follows.
-
Define the rules in the application configuration resource file.
-
Refer to an outcome
String
from the button or link component’saction
attribute. This outcomeString
is used by the Jakarta Server Faces implementation to select the navigation rule.
Here is an example navigation rule:
<navigation-rule>
<from-view-id>/greeting.xhtml</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/response.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
This rule states that when a command component (such as an
h:commandButton
or an h:commandLink
) on greeting.xhtml
is
activated, the application will navigate from the greeting.xhtml
page
to the response.xhtml
page if the outcome referenced by the button
component’s tag is success
. Here is an h:commandButton
tag from
greeting.xhtml
that would specify a logical outcome of success
:
<h:commandButton id="submit" value="Submit" action="success"/>
As the example demonstrates, each navigation-rule
element defines how
to get from one page (specified in the from-view-id
element) to the
other pages of the application. The navigation-rule
elements can
contain any number of navigation-case
elements, each of which defines
the page to open next (defined by to-view-id
) based on a logical
outcome (defined by from-outcome
).
In more complicated applications, the logical outcome can also come from
the return value of an action method in a managed bean. This method
performs some processing to determine the outcome. For example, the
method can check whether the password the user entered on the page
matches the one on file. If it does, the method might return success
;
otherwise, it might return failure
. An outcome of failure
might
result in the logon page being reloaded. An outcome of success
might
cause the page displaying the user’s credit card activity to open. If
you want the outcome to be returned by a method on a bean, you must
refer to the method using a method expression with the action
attribute, as shown by this example:
<h:commandButton id="submit" value="Submit"
action="#{cashierBean.submit}" />
When the user clicks the button represented by this tag, the
corresponding component generates an action event. This event is handled
by the default javax.faces.event.ActionListener
instance, which calls
the action method referenced by the component that triggered the event.
The action method returns a logical outcome to the action listener.
The listener passes the logical outcome and a reference to the action
method that produced the outcome to the default
javax.faces.application.NavigationHandler
. The NavigationHandler
selects the page to display next by matching the outcome or the action
method reference against the navigation rules in the application
configuration resource file by the following process.
-
The
NavigationHandler
selects the navigation rule that matches the page currently displayed. -
It matches the outcome or the action method reference that it received from the default
javax.faces.event.ActionListener
with those defined by the navigation cases. -
It tries to match both the method reference and the outcome against the same navigation case.
-
If the previous step fails, the navigation handler attempts to match the outcome.
-
Finally, the navigation handler attempts to match the action method reference if the previous two attempts failed.
-
If no navigation case is matched, it displays the same view again.
When the NavigationHandler
achieves a match, the Render Response phase
begins. During this phase, the page selected by the NavigationHandler
will be rendered.
The Duke’s Tutoring case study example application uses navigation rules
in the business methods that handle creating, editing, and deleting the
users of the application. For example, the form for creating a student
has the following h:commandButton
tag:
<h:commandButton id="submit"
action="#{adminBean.createStudent(studentManager.newStudent)}"
value="#{bundle['action.submit']}"/>
The action event calls the dukestutoring.ejb.AdminBean.createStudent
method:
public String createStudent(Student student) {
em.persist(student);
return "createdStudent";
}
The return value of createdStudent
has a corresponding navigation case
in the faces-config.xml
configuration file:
<navigation-rule>
<from-view-id>/admin/student/createStudent.xhtml</from-view-id>
<navigation-case>
<from-outcome>createdStudent</from-outcome>
<to-view-id>/admin/index.xhtml</to-view-id>
</navigation-case>
</navigation-rule>
After the student is created, the user is returned to the Administration index page.
For more information on how to define navigation rules, see Configuring Navigation Rules.
For more information on how to implement action methods to handle navigation, see Writing a Method to Handle an Action Event.
For more information on how to reference outcomes or action methods from component tags, see Referencing a Method That Performs Navigation.
4.2.7. The Lifecycle of a Jakarta Server Faces Application
The lifecycle of an application refers to the various stages of processing of that application, from its initiation to its conclusion. All applications have lifecycles. During a web application lifecycle, common tasks are performed, including the following.
-
Handling incoming requests
-
Decoding parameters
-
Modifying and saving state
-
Rendering web pages to the browser
The Jakarta Server Faces web application framework manages lifecycle phases automatically for simple applications or allows you to manage them manually for more complex applications as required.
Jakarta Server Faces applications that use advanced features may require interaction with the lifecycle at certain phases. For example, Ajax applications use partial processing features of the lifecycle (see Partial Processing and Partial Rendering). A clearer understanding of the lifecycle phases is key to creating well-designed components.
A simplified view of the Jakarta Server faces lifecycle, consisting of the two main phases of a Jakarta Server Faces web application, is introduced in A Simple Jakarta Server Faces Application. This section examines the Jakarta Server Faces lifecycle in more detail.
4.2.7.1. Overview of the Jakarta Server Faces Lifecycle
The lifecycle of a Jakarta Server Faces application begins when the client makes an HTTP request for a page and ends when the server responds with the page, translated to HTML.
The lifecycle can be divided into two main phases: Execute and Render. The Execute phase is further divided into subphases to support the sophisticated component tree. This structure requires that component data be converted and validated, component events be handled, and component data be propagated to beans in an orderly fashion.
A Jakarta Server Faces page is represented by a tree of components, called a view. During the lifecycle, the Jakarta Server Faces implementation must build the view while considering the state saved from a previous submission of the page. When the client requests a page, the Jakarta Server Faces implementation performs several tasks, such as validating the data input of components in the view and converting input data to types specified on the server side.
The Jakarta Server Faces implementation performs all these tasks as a series of steps in the Jakarta Server Faces request-response lifecycle. Figure 7-3 illustrates these steps.
The request-response lifecycle handles two kinds of requests: initial requests and postbacks. An initial request occurs when a user makes a request for a page for the first time. A postback request occurs when a user submits the form contained on a page that was previously loaded into the browser as a result of executing an initial request.
When the lifecycle handles an initial request, it executes only the Restore View and Render Response phases, because there is no user input or action to process. Conversely, when the lifecycle handles a postback, it executes all of the phases.
Usually, the first request for a Jakarta Server Faces page comes in from a
client, as a result of clicking a link or button component on a
Jakarta Server Faces page. To render a response that is another Jakarta Server
Faces page, the application creates a new view and stores it in the
javax.faces.context.FacesContext
instance, which represents all of the
information associated with processing an incoming request and creating
a response. The application then acquires object references needed by
the view and calls the FacesContext.renderResponse
method, which
forces immediate rendering of the view by skipping to the
Render Response Phase of the lifecycle, as is shown by the
arrows labelled Render Response in Figure 7-3.
Sometimes, an application might need to redirect to a different web
application resource, such as a web service, or generate a response that
does not contain Jakarta Server Faces components. In these situations, the
developer must skip the Render Response phase by calling the
FacesContext.responseComplete
method. This situation is also shown in
, with the arrows labelled Response Complete.
The most common situation is that a Jakarta Server Faces component submits a request for another Jakarta Server Faces page. In this case, the Jakarta Server Faces implementation handles the request and automatically goes through the phases in the lifecycle to perform any necessary conversions, validations, and model updates and to generate the response.
There is one exception to the lifecycle described in this section. When
a component’s immediate
attribute is set to true
, the validation,
conversion, and events associated with these components are processed
during the Apply Request Values Phase rather than in a
later phase.
The details of the lifecycle explained in the following sections are
primarily intended for developers who need to know information such as
when validations, conversions, and events are usually handled and ways
to change how and when they are handled. For more information on each of
the lifecycle phases, download the latest Jakarta Server Faces Specification
documentation from https://jakarta.ee/specifications/faces/
.
The Jakarta Server Faces application lifecycle Execute phase contains the following subphases:
4.2.7.2. Restore View Phase
When a request for a Jakarta Server Faces page is made, usually by an action, such as when a link or a button component is clicked, the Jakarta Server Faces implementation begins the Restore View phase.
During this phase, the Jakarta Server Faces implementation builds the view
of the page, wires event handlers and validators to components in the
view, and saves the view in the FacesContext
instance, which contains
all the information needed to process a single request. All the
application’s components, event handlers, converters, and validators
have access to the FacesContext
instance.
If the request for the page is an initial request, the Jakarta Server Faces implementation creates an empty view during this phase and the lifecycle advances to the Render Response phase, during which the empty view is populated with the components referenced by the tags in the page.
If the request for the page is a postback, a view corresponding to this
page already exists in the FacesContext
instance. During this phase,
the Jakarta Server Faces implementation restores the view by using the state
information saved on the client or the server.
4.2.7.3. Apply Request Values Phase
After the component tree is restored during a postback request, each
component in the tree extracts its new value from the request parameters
by using its decode
(processDecodes()
) method. The value is then
stored locally on each component.
If any decode
methods or event listeners have called the
renderResponse
method on the current FacesContext
instance, the
Jakarta Server Faces implementation skips to the Render Response phase.
If any events have been queued during this phase, the Jakarta Server Faces implementation broadcasts the events to interested listeners.
If some components on the page have their immediate
attributes (see
The immediate Attribute) set to true
, then
the validations, conversions, and events associated with these
components will be processed during this phase. If any conversion fails,
an error message associated with the component is generated and queued
on FacesContext
. This message will be displayed during the Render
Response phase, along with any validation errors resulting from the
Process Validations phase.
At this point, if the application needs to redirect to a different web
application resource or generate a response that does not contain any
Jakarta Server Faces components, it can call the
FacesContext.responseComplete
method.
At the end of this phase, the components are set to their new values, and messages and events have been queued.
If the current request is identified as a partial request, the partial
context is retrieved from the FacesContext
, and the partial processing
method is applied.
4.2.7.4. Process Validations Phase
During this phase, the Jakarta Server Faces implementation processes all
validators registered on the components in the tree by using its
validate
(processValidators
) method. It examines the component
attributes that specify the rules for the validation and compares these
rules to the local value stored for the component. The Jakarta Server Faces
implementation also completes conversions for input components that do
not have the immediate
attribute set to true.
If the local value is invalid, or if any conversion fails, the
Jakarta Server Faces implementation adds an error message to the
FacesContext
instance, and the lifecycle advances directly to the
Render Response phase so that the page is rendered again with the error
messages displayed. If there were conversion errors from the Apply
Request Values phase, the messages for these errors are also displayed.
If any validate
methods or event listeners have called the
renderResponse
method on the current FacesContext
, the Jakarta Server
Faces implementation skips to the Render Response phase.
At this point, if the application needs to redirect to a different web
application resource or generate a response that does not contain any
Jakarta Server Faces components, it can call the
FacesContext.responseComplete
method.
If events have been queued during this phase, the Jakarta Server Faces implementation broadcasts them to interested listeners.
If the current request is identified as a partial request, the partial
context is retrieved from the FacesContext
, and the partial processing
method is applied.
4.2.7.5. Update Model Values Phase
After the Jakarta Server Faces implementation determines that the data is
valid, it traverses the component tree and sets the corresponding
server-side object properties to the components' local values. The
Jakarta Server Faces implementation updates only the bean properties pointed
at by an input component’s value
attribute. If the local data cannot
be converted to the types specified by the bean properties, the
lifecycle advances directly to the Render Response phase so that the
page is re-rendered with errors displayed. This is similar to what
happens with validation errors.
If any updateModels
methods or any listeners have called the
renderResponse
method on the current FacesContext
instance, the
Jakarta Server Faces implementation skips to the Render Response phase.
At this point, if the application needs to redirect to a different web
application resource or generate a response that does not contain any
Jakarta Server Faces components, it can call the
FacesContext.responseComplete
method.
If any events have been queued during this phase, the Jakarta Server Faces implementation broadcasts them to interested listeners.
If the current request is identified as a partial request, the partial
context is retrieved from the FacesContext
, and the partial processing
method is applied.
4.2.7.6. Invoke Application Phase
During this phase, the Jakarta Server Faces implementation handles any application-level events, such as submitting a form or linking to another page.
At this point, if the application needs to redirect to a different web
application resource or generate a response that does not contain any
Jakarta Server Faces components, it can call the
FacesContext.responseComplete
method.
If the view being processed was reconstructed from state information from a previous request and if a component has fired an event, these events are broadcast to interested listeners.
Finally, the Jakarta Server Faces implementation transfers control to the Render Response phase.
4.2.7.7. Render Response Phase
During this phase, Jakarta Server Faces builds the view and delegates authority to the appropriate resource for rendering the pages.
If this is an initial request, the components that are represented on the page will be added to the component tree. If this is not an initial request, the components are already added to the tree and need not be added again.
If the request is a postback and errors were encountered during the
Apply Request Values phase, Process Validations phase, or Update Model
Values phase, the original page is rendered again during this phase. If
the pages contain h:message
or h:messages
tags, any queued error
messages are displayed on the page.
After the content of the view is rendered, the state of the response is saved so that subsequent requests can access it. The saved state is available to the Restore View phase.
4.2.8. Partial Processing and Partial Rendering
The Jakarta Server Faces lifecycle spans all of the execute and render processes of an application. It is also possible to process and render only parts of an application, such as a single component. For example, the Jakarta Server Faces Ajax framework can generate requests containing information on which particular component may be processed and which particular component may be rendered back to the client.
Once such a partial request enters the Jakarta Server Faces lifecycle, the
information is identified and processed by a
javax.faces.context.PartialViewContext
object. The Jakarta Server Faces
lifecycle is still aware of such Ajax requests and modifies the
component tree accordingly.
The execute
and render
attributes of the f:ajax
tag are used to
identify which components may be executed and rendered. For more
information on these attributes, see Chapter 13,
"Using Ajax with Jakarta Server Faces Technology".
4.2.9. Further Information about Jakarta Server Faces Technology
For more information on Jakarta Server Faces technology, see
-
Jakarta Server Faces 2.3 specification:
-
Mojarra website:
For additional samples, see the (Java EE 8) GlassFish samples at https://github.com/javaee/glassfish-samples/tree/master/ws/javaee8.
4.3. Introduction to Facelets
The term Facelets refers to the view declaration language for Jakarta Server Faces technology. Facelets is a part of the Jakarta Server Faces specification and also the preferred presentation technology for building Jakarta Server Faces technology–based applications. Jakarta Server Pages technology, previously used as the presentation technology for Jakarta Server Faces, does not support all the new features available in Jakarta Server Faces in the Jakarta EE platform. Jakarta Server Pages technology is considered to be a deprecated presentation technology for Jakarta Server Faces.
4.3.1. What Is Facelets?
Facelets is a powerful but lightweight page declaration language that is used to build Jakarta Server Faces views using HTML style templates and to build component trees. Facelets features include the following:
-
Use of XHTML for creating web pages
-
Support for Facelets tag libraries in addition to Jakarta Server Faces and JSTL tag libraries
-
Support for the Expression Language (EL)
-
Templating for components and pages
The advantages of Facelets for large-scale development projects include the following:
-
Support for code reuse through templating and composite components
-
Functional extensibility of components and other server-side objects through customization
-
Faster compilation time
-
Compile-time EL validation
-
High-performance rendering
In short, the use of Facelets reduces the time and effort that needs to be spent on development and deployment.
Facelets views are usually created as XHTML pages. Jakarta Server Faces
implementations support XHTML pages created in conformance with the
XHTML Transitional Document Type Definition (DTD), as listed at
http://www.w3.org/TR/xhtml1/#a_dtd_XHTML-1.0-Transitional
. By
convention, web pages built with XHTML have an .xhtml
extension.
Jakarta Server Faces technology supports various tag libraries to add components to a web page. To support the Jakarta Server Faces tag library mechanism, Facelets uses XML namespace declarations. Table 8-1 lists the tag libraries supported by Facelets.
Table 8-1 Tag Libraries Supported by Facelets
Tag Library |
URI |
Prefix |
Example |
Contents |
Jakarta Server Faces Facelets Tag Library |
|
|
Tags for templating |
|
Jakarta Server Faces HTML Tag Library |
|
|
Jakarta Server Faces component tags for all |
|
Jakarta Server Faces Core Tag Library |
|
|
Tags for Jakarta Server Faces custom actions that are independent of any particular render kit |
|
Pass-through Elements Tag Library |
|
|
Tags to support HTML5-friendly markup |
|
Pass-through Attributes Tag Library |
|
|
Tags to support HTML5-friendly markup |
|
Composite Component Tag Library |
|
|
Tags to support composite components |
|
JSTL Core Tag Library |
|
|
JSTL 1.2 Core Tags |
|
JSTL Functions Tag Library |
|
|
JSTL 1.2 Functions Tags |
Facelets provides two namespaces to support HTML5-friendly markup. For details, see HTML5-Friendly Markup.
Facelets supports tags for composite components, for which you can declare custom prefixes. For more information on composite components, see Composite Components.
The namespace prefixes shown in the table are conventional, not mandatory. As is always the case when you declare an XML namespace, you can specify any prefix in your Facelets page. For example, you can declare the prefix for the composite component tag library as
xmlns:composite="http://xmlns.jcp.org/jsf/composite"
instead of as
xmlns:cc="http://xmlns.jcp.org/jsf/composite"
Based on the Jakarta Server Faces support for Expression Language (EL) syntax, Facelets uses EL expressions to reference properties and methods of managed beans. EL expressions can be used to bind component objects or values to methods or properties of managed beans that are used as backing beans. For more information on using EL expressions, see Using the EL to Reference Managed Beans.
4.3.2. The Lifecycle of a Facelets Application
The Jakarta Server Faces specification defines the lifecycle of a Jakarta Server Faces application. For more information on this lifecycle, see The Lifecycle of a Jakarta Server Faces Application. The following steps describe that process as applied to a Facelets-based application.
-
When a client, such as a browser, makes a new request to a page that is created using Facelets, a new component tree or
javax.faces.component.UIViewRoot
is created and placed in theFacesContext
. -
The
UIViewRoot
is applied to the Facelets, and the view is populated with components for rendering. -
The newly built view is rendered back as a response to the client.
-
On rendering, the state of this view is stored for the next request. The state of input components and form data is stored.
-
The client may interact with the view and request another view or change from the Jakarta Server Faces application. At this time, the saved view is restored from the stored state.
-
The restored view is once again passed through the Jakarta Server Faces lifecycle, which eventually will either generate a new view or re-render the current view if there were no validation problems and no action was triggered.
-
If the same view is requested, the stored view is rendered once again.
-
If a new view is requested, then the process described in Step 2 is continued.
-
The new view is then rendered back as a response to the client.
4.3.3. Developing a Simple Facelets Application: The guessnumber-jsf Example Application
This section describes the general steps involved in developing a Jakarta Server Faces application. The following tasks are usually required:
-
Developing the managed beans
-
Creating the pages using the component tags
-
Defining page navigation
-
Mapping the
FacesServlet
instance -
Adding managed bean declarations
4.3.3.1. Creating a Facelets Application
The example used in this tutorial is the guessnumber-jsf
application.
The application presents you with a page that asks you to guess a number
from 0 to 10, validates your input against a random number, and responds
with another page that informs you whether you guessed the number
correctly or incorrectly.
The source code for this application is in the tut-install`/examples/web/jsf/guessnumber-jsf/` directory.
Developing a Managed Bean
In a typical Jakarta Server Faces application, each page of the application connects to a managed bean that serves as a backing bean. The backing bean defines the methods and properties that are associated with the components. In this example, both pages use the same backing bean.
The following managed bean class, UserNumberBean.java
, generates a
random number from 0 to 10 inclusive:
package ee.jakarta.tutorial.guessnumber;
import java.io.Serializable;
import java.util.Random;
import jakarta.enterprise.context.SessionScoped;
import jakarta.inject.Named;
@Named
@SessionScoped
public class UserNumberBean implements Serializable {
private static final long serialVersionUID = 5443351151396868724L;
Integer randomInt = null;
Integer userNumber = null;
String response = null;
private int maximum = 10;
private int minimum = 0;
public UserNumberBean() {
Random randomGR = new Random();
randomInt = new Integer(randomGR.nextInt(maximum + 1));
// Print number to server log
System.out.println("Duke's number: " + randomInt);
}
public void setUserNumber(Integer user_number) {
userNumber = user_number;
}
public Integer getUserNumber() {
return userNumber;
}
public String getResponse() {
if ((userNumber == null) || (userNumber.compareTo(randomInt) != 0)) {
return "Sorry, " + userNumber + " is incorrect.";
} else {
return "Yay! You got it!";
}
}
public int getMaximum() {
return (this.maximum);
}
public void setMaximum(int maximum) {
this.maximum = maximum;
}
public int getMinimum() {
return (this.minimum);
}
public void setMinimum(int minimum) {
this.minimum = minimum;
}
}
Note the use of the @Named
annotation, which makes the managed bean
accessible through the EL. The @SessionScoped
annotation registers the
bean scope as session
to enable you to make multiple guesses as you
run the application.
Creating Facelets Views
To create a page or view, you add components to the pages, wire the components to backing bean values and properties, and register converters, validators, or listeners on the components.
For the example application, XHTML web pages serve as the front end. The
first page of the example application is a page called greeting.xhtml
.
A closer look at various sections of this web page provides more
information.
The first section of the web page declares the content type for the page, which is XHTML:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
The next section specifies the language of the XHTML page and then declares the XML namespace for the tag libraries that are used in the web page:
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
The next section uses various tags to insert components into the web page:
<h:head>
<h:outputStylesheet library="css" name="default.css"/>
<title>Guess Number Facelets Application</title>
</h:head>
<h:body>
<h:form>
<h:graphicImage value="#{resource['images:wave.med.gif']}"
alt="Duke waving his hand"/>
<h2>
Hi, my name is Duke. I am thinking of a number from
#{userNumberBean.minimum} to #{userNumberBean.maximum}.
Can you guess it?
</h2>
<p><h:inputText id="userNo"
title="Enter a number from 0 to 10:"
value="#{userNumberBean.userNumber}">
<f:validateLongRange minimum="#{userNumberBean.minimum}"
maximum="#{userNumberBean.maximum}"/>
</h:inputText>
<h:commandButton id="submit" value="Submit"
action="response"/>
</p>
<h:message showSummary="true" showDetail="false"
style="color: #d20005;
font-family: 'New Century Schoolbook', serif;
font-style: oblique;
text-decoration: overline"
id="errors1"
for="userNo"/>
</h:form>
</h:body>
Note the use of the following tags:
-
Facelets HTML tags (those beginning with
h:
) to add components -
The Facelets core tag
f:validateLongRange
to validate the user input
An h:inputText
tag accepts user input and sets the value of the
managed bean property userNumber
through the EL expression
#{userNumberBean.userNumber}
. The input value is validated for value
range by the Jakarta Server Faces standard validator tag
f:validateLongRange
.
The image file, wave.med.gif
, is added to the page as a resource, as
is the style sheet. For more details about the resources facility, see
Web Resources.
An h:commandButton
tag with the ID submit
starts validation of the
input data when a user clicks the button. Using implicit navigation, the
tag redirects the client to another page, response.xhtml
, which shows
the response to your input. The page specifies only response
, which by
default causes the server to look for response.xhtml
.
You can now create the second page, response.xhtml
, with the following
content:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<h:outputStylesheet library="css" name="default.css"/>
<title>Guess Number Facelets Application</title>
</h:head>
<h:body>
<h:form>
<h:graphicImage value="#{resource['images:wave.med.gif']}"
alt="Duke waving his hand"/>
<h2>
<h:outputText id="result" value="#{userNumberBean.response}"/>
</h2>
<h:commandButton id="back" value="Back" action="greeting"/>
</h:form>
</h:body>
</html>
This page also uses implicit navigation, setting the action
attribute
for the Back button to send the user to the greeting.xhtml
page.
4.3.3.2. Configuring the Application
Configuring a Jakarta Server Faces application involves mapping the Faces
Servlet in the web deployment descriptor file, such as a web.xml
file,
and possibly adding managed bean declarations, navigation rules, and
resource bundle declarations to the application configuration resource
file, faces-config.xml
.
If you are using NetBeans IDE, a web deployment descriptor file is
automatically created for you. In such an IDE-created web.xml
file,
change the default greeting page, which is index.xhtml
, to
greeting.xhtml
. Here is an example web.xml
file, showing this change
in bold.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd">
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.xhtml</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>greeting.xhtml</welcome-file>
</welcome-file-list>
</web-app>
Note the use of the context parameter PROJECT_STAGE
. This parameter
identifies the status of a Jakarta Server Faces application in the software
lifecycle.
The stage of an application can affect the behavior of the application.
For example, if the project stage is defined as Development
, debugging
information is automatically generated for the user. If not defined by
the user, the default project stage is Production
.
4.3.3.3. Running the guessnumber-jsf Facelets Example
You can use either NetBeans IDE or Maven to build, package, deploy, and
run the guessnumber-jsf
example.
To Build, Package, and Deploy the guessnumber-jsf Example Using NetBeans IDE
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
From the File menu, choose Open Project.
-
In the Open Project dialog box, navigate to:
tut-install/examples/web/jsf
-
Select the
guessnumber-jsf
folder. -
Click Open Project.
-
In the Projects tab, right-click the
guessnumber-jsf
project and select Build.This option builds the example application and deploys it to your GlassFish Server instance.
To Build, Package, and Deploy the guessnumber-jsf Example Using Maven
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
In a terminal window, go to:
tut-install/examples/web/jsf/guessnumber-jsf/
-
Enter the following command:
mvn install
This command builds and packages the application into a WAR file,
guessnumber-jsf.war
, that is located in thetarget
directory. It then deploys it to the server.
To Run the guessnumber-jsf Example
-
Open a web browser.
-
Enter the following URL in your web browser:
http://localhost:8080/guessnumber-jsf
-
In the field, enter a number from 0 to 10 and click Submit.
Another page appears, reporting whether your guess is correct or incorrect.
-
If you guessed incorrectly, click Back to return to the main page.
You can continue to guess until you get the correct answer, or you can look in the server log, where the
UserNumberBean
constructor displays the correct answer.
4.3.4. Using Facelets Templates
Jakarta Server Faces technology provides the tools to implement user interfaces that are easy to extend and reuse. Templating is a useful Facelets feature that allows you to create a page that will act as the base, or template, for the other pages in an application. By using templates, you can reuse code and avoid recreating similarly constructed pages. Templating also helps in maintaining a standard look and feel in an application with a large number of pages.
Table 8-2 lists Facelets tags that are used for templating and their respective functionality.
Table 8-2 Facelets Templating Tags
Tag |
Function |
|
Defines a component that is created and added to the component tree. |
|
Defines a page composition that optionally uses a template. Content outside of this tag is ignored. |
|
Defines a debug component that is created and added to the component tree. |
|
Similar to the composition tag but does not disregard content outside this tag. |
|
Defines content that is inserted into a page by a template. |
|
Similar to the component tag but does not disregard content outside this tag. |
|
Encapsulates and reuses content for multiple pages. |
|
Inserts content into a template. |
|
Used to pass parameters to an included file. |
|
Used as an alternative for loop tags, such as |
|
Removes content from a page. |
For more information on Facelets templating tags, see the Jakarta Server Faces Facelets Tag Library documentation.
The Facelets tag library includes the main templating tag ui:insert
. A
template page that is created with this tag allows you to define a
default structure for a page. A template page is used as a template for
other pages, usually referred to as client pages.
Here is an example of a template saved as template.xhtml
:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8" />
<h:outputStylesheet library="css" name="default.css"/>
<h:outputStylesheet library="css" name="cssLayout.css"/>
<title>Facelets Template</title>
</h:head>
<h:body>
<div id="top" class="top">
<ui:insert name="top">Top Section</ui:insert>
</div>
<div>
<div id="left">
<ui:insert name="left">Left Section</ui:insert>
</div>
<div id="content" class="left_content">
<ui:insert name="content">Main Content</ui:insert>
</div>
</div>
</h:body>
</html>
The example page defines an XHTML page that is divided into three sections: a top section, a left section, and a main section. The sections have style sheets associated with them. The same structure can be reused for the other pages of the application.
The client page invokes the template by using the ui:composition
tag.
In the following example, a client page named templateclient.xhtml
invokes the template page named template.xhtml
from the preceding
example. A client page allows content to be inserted with the help of
the ui:define
tag.
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:body>
<ui:composition template="./template.xhtml">
<ui:define name="top">
Welcome to Template Client Page
</ui:define>
<ui:define name="left">
<h:outputLabel value="You are in the Left Section"/>
</ui:define>
<ui:define name="content">
<h:graphicImage value="#{resource['images:wave.med.gif']}"/>
<h:outputText value="You are in the Main Content Section"/>
</ui:define>
</ui:composition>
</h:body>
</html>
You can use NetBeans IDE to create Facelets template and client pages.
For more information on creating these pages, see
https://netbeans.org/kb/docs/web/jsf20-intro.html
.
4.3.5. Composite Components
Jakarta Server Faces technology offers the concept of composite components with Facelets. A composite component is a special type of template that acts as a component.
Any component is essentially a piece of reusable code that behaves in a particular way. For example, an input component accepts user input. A component can also have validators, converters, and listeners attached to it to perform certain defined actions.
A composite component consists of a collection of markup tags and other existing components. This reusable, user-created component has a customized, defined functionality and can have validators, converters, and listeners attached to it like any other component.
With Facelets, any XHTML page that contains markup tags and other components can be converted into a composite component. Using the resources facility, the composite component can be stored in a library that is available to the application from the defined resources location.
Table 8-3 lists the most commonly used composite tags and their functions.
Table 8-3 Composite Component Tags
Tag |
Function |
|
Declares the usage contract for a composite component. The composite component can be used as a single component whose feature set is the union of the features declared in the usage contract. |
|
Defines the implementation of the composite
component. If a |
|
Declares an attribute that may be given to an instance of the composite component in which this tag is declared. |
|
Any child components or template text
within the composite component tag in the using page will be reparented
into the composite component at the point indicated by this tag’s
placement within the |
|
Declares that the composite component whose
contract is declared by the |
|
Declares that the composite component
whose contract is declared by the |
|
Declares that the composite component whose
contract is declared by the |
For more information and a complete list of Facelets composite tags, see the Jakarta Server Faces Facelets Tag Library documentation.
The following example shows a composite component that accepts an email address as input:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:composite="http://xmlns.jcp.org/jsf/composite"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
<title>This content will not be displayed</title>
</h:head>
<h:body>
<composite:interface>
<composite:attribute name="value" required="false"/>
</composite:interface>
<composite:implementation>
<h:outputLabel value="Email id: "></h:outputLabel>
<h:inputText value="#{cc.attrs.value}"></h:inputText>
</composite:implementation>
</h:body>
</html>
Note the use of cc.attrs.value
when defining the value of the
inputText
component. The word cc
in Jakarta Server Faces is a reserved
word for composite components. The #{cc.attrs.`attribute-name
}`
expression is used to access the attributes defined for the composite
component’s interface, which in this case happens to be value
.
The preceding example content is stored as a file named email.xhtml
in
a folder named resources/emcomp
, under the application web root
directory. This directory is considered a library by Jakarta Server Faces,
and a component can be accessed from such a library. For more
information on resources, see Web
Resources.
The web page that uses this composite component is generally called a
using page. The using page includes a reference to the composite
component, in the xml
namespace declarations:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:em="http://xmlns.jcp.org/jsf/composite/emcomp">
<h:head>
<title>Using a sample composite component</title>
</h:head>
<body>
<h:form>
<em:email value="Enter your email id" />
</h:form>
</body>
</html>
The local composite component library is defined in the xmlns
namespace with the declaration
xmlns:em="http://xmlns.jcp.org/jsf/composite/emcomp"
. The component
itself is accessed through the em:email
tag. The preceding example
content can be stored as a web page named emuserpage.xhtml
under the
web root directory. When compiled and deployed on a server, it can be
accessed with the following URL:
http://localhost:8080/application-name/emuserpage.xhtml
See Chapter 14, "Composite Components: Advanced Topics and an Example," for more information and an example.
4.3.6. Web Resources
Web resources are any software artifacts that the web application requires for proper rendering, including images, script files, and any user-created component libraries. Resources must be collected in a standard location, which can be one of the following.
-
A resource packaged in the web application root must be in a subdirectory of a
resources
directory at the web application root: `resources/`resource-identifier. -
A resource packaged in the web application’s classpath must be in a subdirectory of the
META-INF/resources
directory within a web application: `META-INF/resources/`resource-identifier. You can use this file structure to package resources in a JAR file bundled in the web application.
The Jakarta Server Faces runtime will look for the resources in the preceding listed locations, in that order.
Resource identifiers are unique strings that conform to the following format (all on one line):
[locale-prefix/][library-name/][library-version/]resource-name[/resource-version]
Elements of the resource identifier in brackets ([]
) are optional,
indicating that only a resource-name, which is usually a file name, is a
required element. For example, the most common way to specify a style
sheet, image, or script is to use the library
and name
attributes,
as in the following tag from the guessnumber-jsf
example:
<h:outputStylesheet library="css" name="default.css"/>
This tag specifies that the default.css
style sheet is in the
directory web/resources/css
.
You can also specify the location of an image using the following
syntax, also from the guessnumber-jsf
example:
<h:graphicImage value="#{resource['images:wave.med.gif']}"/>
This tag specifies that the image named wave.med.gif
is in the
directory web/resources/images
.
Resources can be considered as a library location. Any artifact, such as
a composite component or a template that is stored in the resources
directory, becomes accessible to the other application components, which
can use it to create a resource instance.
4.3.7. Relocatable Resources
You can place a resource tag in one part of a page and specify that it
be rendered in another part of the page. To do this, you use the
target
attribute of a tag that specifies a resource. Acceptable values
for this attribute are as follows.
-
"head"
renders the resource in thehead
element. -
"body"
renders the resource in thebody
element. -
"form"
renders the resource in theform
element.
For example, the following h:outputScript
tag is placed within an
h:form
element, but it renders the JavaScript in the head
element:
<h:form>
<h:outputScript name="myscript.js" library="mylibrary" target="head"/>
</h:form>
The h:outputStylesheet
tag also supports resource relocation, in a
similar way.
Relocatable resources are essential for composite components that use stylesheets and can also be useful for composite components that use JavaScript. See The compositecomponentexample Example Application for an example.
4.3.8. Resource Library Contracts
Resource library contracts allow you to define a different look and feel for different parts of one or more applications, instead of either having to use the same look and feel for all or having to specify a different look on a page-by-page basis.
To do this, you create a contracts
section of your web application.
Within the contracts
section, you can specify any number of named
areas, each of which is called a contract. Within each contract you can
specify resources such as template files, stylesheets, JavaScript files,
and images.
For example, you could specify two contracts named c1
and c2
, each
of which uses a template and other files:
src/main/webapp
WEB-INF/
contracts
c1
template.xhtml
style.css
myImg.gif
myJS.js
c2
template.xhtml
style2.css
img2.gif
JS2.js
index.xhtml
...
One part of the application can use c1
, while another can use c2
.
Another way to use contracts is to specify a single contract that contains multiple templates:
src/main/webapp
contracts
myContract
template1.xhtml
template2.xhtml
style.css
img.png
img2.png
You can package a resource library contract in a JAR file for reuse in
different applications. If you do so, the contracts must be located
under META-INF/contracts
. You can then place the JAR file in the
WEB-INF/lib
directory of an application. This means that the
application would be organized as follows:
src/main/webapp/
WEB-INF/lib/myContract.jar
...
You can specify the contract usage within an application’s
faces-config.xml
file, under the resource-library-contracts
element.
You need to use this element only if your application uses more than one
contract, however.
4.3.8.1. The hello1-rlc Example Application
The hello1-rlc
example modifies the simple hello1
example from
A Web Module That Uses Jakarta Server Faces
Technology: The hello1 Example to use two resource library contracts.
Each of the two pages in the application uses a different contract.
The managed bean for hello1-rlc
, Hello.java
, is identical to the one
for hello1
(except that it replaces the @Named
and @RequestScoped
annotations with @Model
).
The source code for this application is in the tut-install`/examples/web/jsf/hello1-rlc/` directory.
Configuring the hello1-rlc Example
The faces-config.xml
file for the hello1-rlc
example contains the
following elements:
<resource-library-contracts>
<contract-mapping>
<url-pattern>/reply/*</url-pattern>
<contracts>reply</contracts>
</contract-mapping>
<contract-mapping>
<url-pattern>*</url-pattern>
<contracts>hello</contracts>
</contract-mapping>
</resource-library-contracts>
The contract-mapping
elements within the resource-library-contracts
element map each contract to a different set of pages within the
application. One contract, named reply
, is used for all pages under
the reply
area of the application (/reply/
). The other contract,
hello
, is used for all other pages in the application ().
The application is organized as follows:
hello1-rlc
pom.xml
src/main/java/ee/jakarta/tutorial/hello1rlc/Hello.java
src/main/webapp
WEB-INF
faces-config.xml
web.xml
contracts
hello
default.css
duke.handsOnHips.gif
template.xhtml
reply
default.css
duke.thumbsup.gif
template.xhtml
reply
response.xhtml
greeting.xhtml
The web.xml
file specifies the welcome-file
as greeting.xhtml
.
Because it is not located under src/main/webapp/reply
, this Facelets
page uses the hello
contract, whereas
src/main/webapp/reply/response.xhtml
uses the reply
contract.
The Facelets Pages for the hello1-rlc Example
The greeting.xhtml
and response.xhtml
pages have identical code
calling in their templates:
<ui:composition template="/template.xhtml">
The template.xhtml
files in the hello
and reply
contracts differ
only in two respects: the placeholder text for the title
element
("Hello Template" and "Reply Template") and the graphic that each
specifies.
The default.css
stylesheets in the two contracts differ in only one
respect: the background color specified for the body
element.
To Build, Package, and Deploy the hello1-rlc Example Using NetBeans IDE
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
From the File menu, choose Open Project.
-
In the Open Project dialog box, navigate to:
tut-install/examples/web/jsf
-
Select the
hello1-rlc
folder. -
Click Open Project.
-
In the Projects tab, right-click the
hello1-rlc
project and select Build.This option builds the example application and deploys it to your GlassFish Server instance.
To Build, Package, and Deploy the hello1-rlc Example Using Maven
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
In a terminal window, go to:
tut-install/examples/web/jsf/hello1-rlc/
-
Enter the following command:
mvn install
This command builds and packages the application into a WAR file,
hello1-rlc.war
, that is located in thetarget
directory. It then deploys it to your GlassFish Server instance.
To Run the hello1-rlc Example
-
Enter the following URL in your web browser:
http://localhost:8080/hello1-rlc
-
The
greeting.xhtml
page looks just like the one fromhello1
except for its background color and graphic. -
In the text field, enter your name and click Submit.
-
The response page also looks just like the one from
hello1
except for its background color and graphic.The page displays the name you submitted. Click Back to return to the
greeting.xhtml
page.
4.3.9. HTML5-Friendly Markup
When you want to produce user interface features for which HTML does not have its own elements, you can create a custom Jakarta Server Faces component and insert it in your Facelets page. This mechanism can cause a simple element to create complex web code. However, creating such a component is a significant task (see Chapter 15, "Creating Custom UI Components and Other Custom Objects").
HTML5 offers new elements and attributes that can make it unnecessary to write your own components. It also provides many new capabilities for existing components. Jakarta Server Faces technology supports HTML5 not by introducing new UI components that imitate HTML5 ones but by allowing you to use HTML5 markup directly. It also allows you to use Jakarta Server Faces attributes within HTML5 elements. Jakarta Server Faces technology support for HTML5 falls into two categories:
-
Pass-through elements
-
Pass-through attributes
The effect of the HTML5-friendly markup feature is to offer the Facelets page author almost complete control over the rendered page output, rather than having to pass this control off to component authors. You can mix and match Jakarta Server Faces and HTML5 components and elements as you see fit.
4.3.9.1. Using Pass-Through Elements
Pass-through elements allow you to use HTML5 tags and attributes but to
treat them as equivalent to Jakarta Server Faces components associated with
a server-side UIComponent
instance.
To make an element that is not a Jakarta Server Faces element a pass-through
element, specify at least one of its attributes using the
http://xmlns.jcp.org/jsf
namespace. For example, the following code
declares the namespace with the short name jsf
:
<html ... xmlns:jsf="http://xmlns.jcp.org/jsf"
...
<input type="email" jsf:id="email" name="email"
value="#{reservationBean.email}" required="required"/>
Here, the jsf
prefix is placed on the id
attribute so that the HTML5
input tag’s attributes are treated as part of the Facelets page. This
means that, for example, you can use EL expressions to retrieve managed
bean properties.
Table 8-4 shows how pass-through elements are rendered as Facelets tags. The server faces implementation uses the element name and the identifying attribute to determine the corresponding Facelets tag that will be used in the server-side processing. The browser, however, interprets the markup that the page author has written.
Table 8-4 How Facelets Renders HTML5 Elements
HTML5 Element Name |
Identifying Attribute |
Facelets Tag |
|
|
|
|
|
|
|
|
|
|
|
|
|
+ |
|
|
+ |
|
|
|
|
|
+ |
|
|
+ |
|
|
+ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
+ |
|
|
+ |
|
|
+ |
|
|
|
|
|
+ |
|
|
+ |
|
4.3.9.2. Using Pass-Through Attributes
Pass-through attributes are the converse of pass-through elements. They
allow you to pass attributes that are not Jakarta Server Faces attributes
through to the browser without interpretation. If you specify a
pass-through attribute in a Jakarta Server Faces UIComponent
, the
attribute name and value are passed straight through to the browser
without being interpreted by Jakarta Server Faces components or renderers.
There are several ways to specify pass-through attributes.
-
Use the Jakarta Server Faces namespace for pass-through attributes to prefix the attribute names within a Jakarta Server Faces component. For example, the following code declares the namespace with the short name
p
, then passes thetype
,min
,max
,required
, andtitle
attributes through to the HTML5input
component:<html ... xmlns:p="http://xmlns.jcp.org/jsf/passthrough" ... <h:form prependId="false"> <h:inputText id="nights" p:type="number" value="#{bean.nights}" p:min="1" p:max="30" p:required="required" p:title="Enter a number between 1 and 30 inclusive."> ...
This will cause the following markup to be rendered (assuming that
bean.nights
has a default value set to 1):<input id="nights" type="number" value="1" min="1" max="30" required="required" title="Enter a number between 1 and 30 inclusive.">
-
To pass a single attribute, nest the
f:passThroughAttribute
tag within a component tag. For example:<h:inputText value="#{user.email}"> <f:passThroughAttribute name="type" value="email" /> </h:inputText>
This code would be rendered similarly to the following:
<input value="me@me.com" type="email" />
-
To pass a group of attributes, nest the
f:passThroughAttributes
tag within a component tag, specifying an EL value that must evaluate to aMap<String, Object>
. For example:<h:inputText value="#{bean.nights"> <f:passThroughAttributes value="#{bean.nameValuePairs}" /> </h:inputText>
If the bean used the following
Map
declaration and initialized the map in the constructor as follows, the markup would be similar to the output of the code that uses the pass-through attribute namespace:private Map<String, Object> nameValuePairs; ... public Bean() { this.nameValuePairs = new HashMap<>(); this.nameValuePairs.put("type", "number"); this.nameValuePairs.put("min", "1"); this.nameValuePairs.put("max", "30"); this.nameValuePairs.put("required", "required"); this.nameValuePairs.put("title", "Enter a number between 1 and 4 inclusive."); }
4.3.9.3. The reservation Example Application
The reservation
example application provides a set of HTML5 input
elements of various types to simulate purchasing tickets for a
theatrical event. It consists of two Facelets pages, reservation.xhtml
and confirmation.xhtml
, and a backing bean, ReservationBean.java
.
The pages use both pass-through attributes and pass-through elements.
The source code for this application is in the tut-install`/examples/web/jsf/reservation/` directory.
The Facelets Pages for the reservation Application
The first important feature of the Facelets pages for the reservation
application is the DOCTYPE
header. Most Facelets pages in Jakarta Server
Faces applications refer to the XHTML DTD. The facelets pages for this
application begin simply with the following DOCTYPE
header, which
indicates an HTML5 page:
<!DOCTYPE html>
The namespace declarations in the html
element of the
reservation.xhtml
page specify both the jsf
and the passthrough
namespaces:
<html lang="en"
xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://xmlns.jcp.org/jsf/passthrough"
xmlns:jsf="http://xmlns.jcp.org/jsf">
Next, an empty h:head
tag followed by an h:outputStylesheet
tag
within the h:body
tag illustrates the use of a relocatable resource
(as described in Relocatable
Resources):
<h:head>
</h:head>
<h:body>
<h:outputStylesheet name="css/stylesheet.css" target="head"/>
The reservation.xhtml
page uses pass-through elements for most of the
form fields on the page. This allows it to use some HTML5-specific
input
element types, such as date
and email
. For example, the
following element renders both a date format and a calendar from which
you can choose a date. The jsf
prefix on the id
attribute makes the
element a pass-through one:
<input type="date" jsf:id="date" name="date"
value="#{reservationBean.date}" required="required"
title="Enter or choose a date."/>
The field for the number of tickets, however, uses the
h:passThroughAttributes
tag to pass a Map
defined in the managed
bean. It also recalculates the total in response to a change in the
field:
<h:inputText id="tickets" value="#{reservationBean.tickets}">
<f:passThroughAttributes value="#{reservationBean.ticketAttrs}"/>
<f:ajax event="change" render="total"
listener="#{reservationBean.calculateTotal}"/>
</h:inputText>
The field for the price specifies the number
type as a pass-through
attribute of the h:inputText
element, offering a range of four ticket
prices. Here, the p
prefix on the HTML5 attributes passes them through
to the browser uninterpreted by the Jakarta Server Faces input component:
<h:inputText id="price" p:type="number"
value="#{reservationBean.price}"
p:min="80" p:max="120"
p:step="20" p:required="required"
p:title="Enter a price: 80, 100, 120, or 140.">
<f:ajax event="change" render="total"
listener="#{reservationBean.calculateTotal}"/>
</h:inputText>
The output of the calculateTotal
method that is specified as the
listener for the Ajax event is rendered in the output element whose id
and name
value is total
. See Chapter 13,
"Using Ajax with Jakarta Server Faces Technology", for more information.
The second Facelets page, confirmation.xhtml
, uses a pass-through
output
element to display the values entered by the user and provides
a Facelets h:commandButton
tag to allow the user to return to the
reservation.xhtml
page.
The Managed Bean for the reservation Application
The session-scoped managed bean for the reservation application,
ReservationBean.java
, contains properties for all the elements on the
Facelets pages. It also contains two methods, calculateTotal
and
clear
, that act as listeners for Ajax events on the
reservation.xhtml
page.
To Build, Package, and Deploy the reservation Example Using NetBeans IDE
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
From the File menu, choose Open Project.
-
In the Open Project dialog box, navigate to:
tut-install/examples/web/jsf
-
Select the
reservation
folder. -
Click Open Project.
-
In the Projects tab, right-click the
reservation
project and select Build.This option builds the example application and deploys it to your GlassFish Server instance.
To Build, Package, and Deploy the reservation Example Using Maven
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
In a terminal window, go to:
tut-install/examples/web/jsf/reservation/
-
Enter the following command:
mvn install
This command builds and packages the application into a WAR file,
reservation.war
, that is located in thetarget
directory. It then deploys the WAR file to your GlassFish Server instance.
To Run the reservation Example
At the time of the publication of this tutorial, the browser that most fully implements HTML5 is Google Chrome, and it is recommended that you use it to run this example. Other browsers are catching up, however, and may work equally well by the time you read this.
-
Enter the following URL in your web browser:
http://localhost:8080/reservation
-
Enter information in the fields of the
reservation.xhtml
page.The Performance Date field has a date field with up and down arrows that allow you to increment and decrement the month, day, and year as well as a larger down arrow that brings up a date editor in calendar form.
The Number of Tickets and Ticket Price fields also have up and down arrows that allow you to increment and decrement the values within the allowed range and steps. The Estimated Total changes when you change either of these two fields.
Email addresses and dates are checked for format, but not for validity (you can make a reservation for a past date, for instance).
-
Click Make Reservation to complete the reservation or Clear to restore the fields to their default values.
-
If you click Make Reservation, the
confirmation.xhtml
page appears, displaying the submitted values.Click Back to return to the
reservation.xhtml
page.
4.4. Expression Language
This chapter introduces the Expression Language (also referred to as the EL), which provides an important mechanism for enabling the presentation layer (web pages) to communicate with the application logic (managed beans). The EL is used by several Jakarta EE technologies, such as Jakarta Server Faces technology, Jakarta Server Pages technology, and Dependency Injection for Jakarta EE (CDI). The EL can also be used in stand-alone environments. This chapter only covers the use of the EL in Jakarta EE containers.
4.4.1. Overview of the EL
The EL allows page authors to use simple expressions to dynamically
access data from JavaBeans components. For example, the test
attribute
of the following conditional tag is supplied with an EL expression that
compares 0 with the number of items in the session-scoped bean named
cart
.
<c:if test="${sessionScope.cart.numberOfItems > 0}">
...
</c:if>
See Using the EL to Reference Managed Beans for more information on how to use the EL in Jakarta Server Faces applications.
To summarize, the EL provides a way to use simple expressions to perform the following tasks:
-
Dynamically read application data stored in JavaBeans components, various data structures, and implicit objects
-
Dynamically write data, such as user input into forms, to JavaBeans components
-
Invoke arbitrary static and public methods
-
Dynamically perform arithmetic, boolean, and string operations
-
Dynamically construct collection objects and perform operations on collections
In a Jakarta Server Faces page, an EL expression can be used either in static text or in the attribute of a custom tag or standard action.
Finally, the EL provides a pluggable API for resolving expressions so that custom resolvers that can handle expressions not already supported by the EL can be implemented.
4.4.2. Immediate and Deferred Evaluation Syntax
The EL supports both immediate and deferred evaluation of expressions. Immediate evaluation means that the expression is evaluated and the result returned as soon as the page is first rendered. Deferred evaluation means that the technology using the expression language can use its own machinery to evaluate the expression sometime later during the page’s lifecycle, whenever it is appropriate to do so.
Those expressions that are evaluated immediately use the ${}
syntax.
Expressions whose evaluation is deferred use the #{}
syntax.
Because of its multiphase lifecycle, Jakarta Server Faces technology uses mostly deferred evaluation expressions. During the lifecycle, component events are handled, data is validated, and other tasks are performed in a particular order. Therefore, a Jakarta Server Faces implementation must defer evaluation of expressions until the appropriate point in the lifecycle.
Other technologies using the EL might have different reasons for using deferred expressions.
4.4.2.1. Immediate Evaluation
All expressions using the ${}
syntax are evaluated immediately. These
expressions can appear as part of a template (static) text or as the
value of a tag attribute that can accept runtime expressions.
The following example shows a tag whose value
attribute references an
immediate evaluation expression that updates the quantity of books
retrieved from the backing bean named catalog
:
<h:outputText value="${catalog.bookQuantity}" />
The Jakarta Server Faces implementation evaluates the expression
${catalog.bookQuantity}
, converts it, and passes the returned value to
the tag handler. The value is updated on the page.
4.4.2.2. Deferred Evaluation
Deferred evaluation expressions take the form #{expr}
and can be
evaluated at other phases of a page lifecycle as defined by whatever
technology is using the expression. In the case of Jakarta Server Faces
technology, its controller can evaluate the expression at different
phases of the lifecycle, depending on how the expression is being used
in the page.
The following example shows a Jakarta Server Faces h:inputText
tag, which
represents a field component into which a user enters a value. The
h:inputText
tag’s value
attribute references a deferred evaluation
expression that points to the name
property of the customer
bean:
<h:inputText id="name" value="#{customer.name}" />
For an initial request of the page containing this tag, the Jakarta Server
Faces implementation evaluates the #{customer.name}
expression during
the render-response phase of the lifecycle. During this phase, the
expression merely accesses the value of name
from the customer
bean,
as is done in immediate evaluation.
For a postback request, the Jakarta Server Faces implementation evaluates
the expression at different phases of the lifecycle, during which the
value is retrieved from the request, validated, and propagated to the
customer
bean.
As shown in this example, deferred evaluation expressions can be
-
Value expressions that can be used to both read and write data
-
Method expressions
Value expressions (both immediate and deferred) and method expressions are explained in the next section.
4.4.3. Value and Method Expressions
The EL defines two kinds of expressions: value expressions and method expressions. Value expressions can be evaluated to yield a value, and method expressions are used to reference a method.
4.4.3.1. Value Expressions
Value expressions can be further categorized into rvalue and lvalue expressions. An lvalue expression can specify a target, such as an object, a bean property, or elements of a collection, that can be assigned a value. An rvalue expression cannot specify such a target.
All expressions that are evaluated immediately use the ${}
delimiters,
and although the expression can be an lvalue expression, no assignments
will ever happen. Expressions whose evaluation can be deferred use the
#{}
delimiters and can act as both rvalue and lvalue expressions; if
the expression is an lvalue expression, it can be assigned a new value.
Consider the following two value expressions:
${customer.name}
#{customer.name}
The former uses immediate evaluation syntax, whereas the latter uses
deferred evaluation syntax. The first expression accesses the name
property, gets its value, and passes the value to the tag handler. With
the second expression, the tag handler can defer the expression
evaluation to a later time in the page lifecycle if the technology using
this tag allows.
In the case of Jakarta Server Faces technology, the latter tag’s expression
is evaluated immediately during an initial request for the page. During
a postback request, this expression can be used to set the value of the
name
property with user input.
Referencing Objects
A top-level identifier (such as customer
in the expression
customer.name
) can refer to the following objects:
-
Lambda parameters
-
EL variables
-
Managed beans
-
Implicit objects
-
Classes of static fields and methods
To refer to these objects, you write an expression using a variable that
is the name of the object. The following expression references a managed
bean called customer
:
${customer}
You can use a custom EL resolver to alter the way variables are
resolved. For instance, you can provide an EL resolver that intercepts
objects with the name customer
, so that ${customer}
returns a value
in the EL resolver instead. (Jakarta Server Faces technology uses an EL
resolver to handle managed beans.)
An enum
constant is a special case of a static field, and you can
reference such a constant directly. For example, consider this enum
class:
public enum Suit {hearts, spades, diamonds, clubs}
In the following expression, in which mySuit
is an instance of Suit
,
you can compare suit.hearts
to the instance:
${mySuit == suit.hearts}
Referencing Object Properties or Collection Elements
To refer to properties of a bean, static fields or methods of a class,
or items of a collection, you use the .
or []
notation. The same
syntax can be used for attributes of an implicit object, because
attributes are placed in a map.
To reference the name
property of the customer
bean, use either the
expression ${customer.name}
or the expression ${customer["name"]}
.
Here, the part inside the brackets is a String
literal that is the
name of the property to reference. The []
syntax is more general than
the .
syntax, because the part inside the brackets can be any String
expression, not just literals.
You can use double or single quotes for the String
literal. You can
also combine the []
and .
notations, as shown here:
${customer.address["street"]}
You can reference a static field or method using the syntax classname.field, as in the following example:
Boolean.FALSE
The classname is the name of the class without the package name. By
default, all the java.lang
packages are imported. You can import other
packages, classes, and static fields as needed.
If you are accessing an item in an array or list, you must use the []
notation and specify an index in the array or list. The index is an
expression that can be converted to int
. The following example
references the first of the customer orders, assuming that
customer.orders
is a List
:
${customer.orders[1]}
If you are accessing an item in a Map
, you must specify the key for
the Map
. If the key is a String
literal, the dot (.)
notation can
be used. Assuming that customer.orders
is a Map
with a String
key,
the following examples reference the item with the key "socks"
:
${customer.orders["socks"]}
${customer.orders.socks}
Referencing Literals
The EL defines the following literals:
-
Boolean:
true
andfalse
-
Integer: As in Java
-
Floating-point: As in Java
-
String: With single and double quotes;
"
is escaped as\"
,'
is escaped as\'
, and\
is escaped as\\
-
Null:
null
Here are some examples:
-
${"literal"}
-
${true}
-
${57}
Parameterized Method Calls
The EL offers support for parameterized method calls.
Both the .
and []
operators can be used for invoking method calls
with parameters, as shown in the following expression syntax:
-
expr-a`[
expr-b
](parameters
)` -
expr-a`.
identifier-b
(parameters
)`
In the first expression syntax, expr-a is evaluated to represent a bean object. The expression expr-b is evaluated and cast to a string that represents a method in the bean represented by expr-a. In the second expression syntax, expr-a is evaluated to represent a bean object, and identifier-b is a string that represents a method in the bean object. The parameters in parentheses are the arguments for the method invocation. Parameters can be zero or more values of expressions, separated by commas.
Parameters are supported for both value expressions and method
expressions. In the following example, which is a modified tag from the
guessnumber
application, a random number is provided as an argument
rather than from user input to the method call:
<h:inputText value="#{userNumberBean.userNumber('5')}">
The preceding example uses a value expression.
Consider the following example of a Jakarta Server Faces component tag that uses a method expression:
<h:commandButton action="#{trader.buy}" value="buy"/>
The EL expression trader.buy
calls the trader
bean’s buy
method.
You can modify the tag to pass on a parameter. Here is the revised tag
in which a parameter is passed:
<h:commandButton action="#{trader.buy('SOMESTOCK')}" value="buy"/>
In the preceding example, you are passing the string 'SOMESTOCK'
(a
stock symbol) as a parameter to the buy
method.
Where Value Expressions Can Be Used
Value expressions using the ${}
delimiters can be used
-
In static text
-
In any standard or custom tag attribute that can accept an expression
The value of an expression in static text is computed and inserted into the current output. Here is an example of an expression embedded in static text:
<some:tag>
some text ${expr} some text
</some:tag>
A tag attribute can be set in the following ways.
-
With a single expression construct:
<some:tag value="${expr}"/> <another:tag value="#{expr}"/>
These expressions are evaluated, and the result is converted to the attribute’s expected type.
-
With one or more expressions separated or surrounded by text:
<some:tag value="some${expr}${expr}text${expr}"/> <another:tag value="some#{expr}#{expr}text#{expr}"/>
These kinds of expression, called composite expressions, are evaluated from left to right. Each expression embedded in the composite expression is converted to a
String
and then concatenated with any intervening text. The resultingString
is then converted to the attribute’s expected type. -
With text only:
<some:tag value="sometext"/>
The attribute’s
String
value is converted to the attribute’s expected type.
You can use the string concatenation operator += to create a single expression from what would otherwise be a composite expression. For example, you could change the composite expression
<some:tag value="sometext ${expr} moretext"/>
to
<some:tag value="${sometext += expr += moretext}"/>
All expressions used to set attribute values are evaluated in the
context of an expected type. If the result of the expression evaluation
does not match the expected type exactly, a type conversion will be
performed. For example, the expression ${1.2E4}
provided as the value
of an attribute of type float
will result in the following conversion:
Float.valueOf("1.2E4").floatValue()
4.4.3.2. Method Expressions
Another feature of the EL is its support of deferred method expressions. A method expression is used to refer to a public method of a bean and has the same syntax as an lvalue expression.
In Jakarta Server Faces technology, a component tag represents a component on a page. The component tag uses method expressions to specify methods that can be invoked to perform some processing for the component. These methods are necessary for handling events that the components generate and for validating component data, as shown in this example:
<h:form>
<h:inputText id="name"
value="#{customer.name}"
validator="#{customer.validateName}"/>
<h:commandButton id="submit"
action="#{customer.submit}" />
</h:form>
The h:inputText
tag displays as a field. The validator
attribute of
this h:inputText
tag references a method, called validateName
, in
the bean, called customer
.
Because a method can be invoked during different phases of the lifecycle, method expressions must always use the deferred evaluation syntax.
Like lvalue expressions, method expressions can use the .
and the []
operators. For example, #{object.method}
is equivalent to
#{object["method"]}
. The literal inside the []
is converted to
String
and is used to find the name of the method that matches it.
Method expressions can be used only in tag attributes and only in the following ways:
-
With a single expression construct, where bean refers to a JavaBeans component and method refers to a method of the JavaBeans component:
<some:tag value="#{bean.method}"/>
The expression is evaluated to a method expression, which is passed to the tag handler. The method represented by the method expression can then be invoked later.
-
With text only:
<some:tag value="sometext"/>
Method expressions support literals primarily to support
action
attributes in Jakarta Server Faces technology. When the method referenced by this method expression is invoked, the method returns theString
literal, which is then converted to the expected return type, as defined in the tag’s tag library descriptor.
4.4.3.3. Lambda Expressions
A lambda expression is a value expression with parameters. The syntax is similar to that of the lambda expression in the Java programming language, except that in the EL, the body of the lambda expression is an EL expression.
For basic information on lambda expressions, see
http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html
.
Note: Lambda expressions are part of Java SE 8, but you can use them in EL expressions with Java SE 7, the Java version associated with the Jakarta EE 7 platform. |
A lambda expression uses the arrow token (→)
operator. The
identifiers to the left of the operator are called lambda parameters.
The body, to the right of the operator, must be an EL expression. The
lambda parameters are enclosed in parentheses; the parentheses can be
omitted if there is only one parameter. Here are some examples:
x -> x+1
(x, y) -> x + y
() -> 64
A lambda expression behaves like a function. It can be invoked immediately. For example, the following invocation evaluates to 7:
((x, y) -> x + y)(3, 4)
You can use a lambda expression in conjunction with the assignment and semicolon operators. For example, the following code assigns the previous lambda expression to a variable and then invokes it. The result is again 7:
v = (x, y) -> x + y; v(3, 4)
A lambda expression can also be passed as an argument to a method and be invoked in the method. It can also be nested in another lambda expression.
4.4.4. Operations on Collection Objects
The EL supports operations on collection objects: sets, lists, and maps. It allows the dynamic creation of collection objects, which can then be operated on using streams and pipelines.
Note: Like lambda expressions, operations on collection objects are part of Java SE 8. |
For example, you can construct a set as follows:
{1,2,3}
You can construct a list as follows; a list can contain various types of items:
[1,2,3]
[1, "two", [three,four]]
You can construct a map by using a colon to define the entries, as follows:
{"one":1, "two":2, "three":3}
You operate on collection objects using method calls to the stream of elements derived from the collection. Some operations return another stream, which allows additional operations. Therefore, you can chain these operations together in a pipeline.
A stream pipeline consists of the following:
-
A source (the
Stream
object) -
Any number of intermediate operations that return a stream (for example,
filter
andmap
) -
A terminal operation that does not return a stream (for example,
toList()
)
The stream
method obtains a Stream
from a java.util.Collection
or
a Java array. The stream operations do not modify the original
collection object.
For example, you might generate a list of titles of history books as follows:
books.stream().filter(b->b.category == 'history')
.map(b->b.title)
.toList()
The following simpler example returns a sorted version of the original list:
[1,3,5,2].stream().sorted().toList()
Streams and stream operations are documented in the Java SE 8 API
documentation, available at http://docs.oracle.com/javase/8/docs/api/
.
The following subset of operations is supported by the EL:
allMatch
anyMatch
average
count
distinct
filter
findFirst
flatMap
forEach
iterator
limit
map
max
min
noneMatch
peek
reduce
sorted
substream
sum
toArray
toList
See the EL specification at http://www.jcp.org/en/jsr/detail?id=341
for details on these operations.
4.4.5. Operators
In addition to the .
and []
operators discussed in
Value and Method Expressions, the EL provides
the following operators, which can be used in rvalue expressions only.
-
Arithmetic:
+
,-
(binary),*
,/
anddiv
,%
andmod
,-
(unary). -
String concatenation:
+=
. -
Logical:
and
,&&
,or
,||
,not
,!
. -
Relational:
==
,eq
,!=
,ne
,<
,lt
,>
,gt
,⇐
,ge
,>=
,le
. Comparisons can be made against other values or against Boolean, string, integer, or floating-point literals. -
Empty: The
empty
operator is a prefix operation that can be used to determine whether a value isnull
or empty. -
Conditional:
A ? B : C
. EvaluateB
orC
, depending on the result of the evaluation ofA
. -
Lambda expression:
→
, the arrow token. -
Assignment:
=
. -
Semicolon:
;
.
The precedence of operators, highest to lowest, left to right, is as follows:
-
[] .
-
()
(used to change the precedence of operators) -
-
(unary)not ! empty
-
* / div % mod
-
+ -
(binary) -
+=
-
<> ⇐ >= lt gt le ge
-
== != eq ne
-
&& and
-
|| or
-
? :
-
→
-
=
-
;
4.4.6. Reserved Words
The following words are reserved for the EL and should not be used as identifiers:
and
or
not
eq
ne
lt
gt
le
ge
true
false
null
instanceof
empty
div
mod
4.4.7. Examples of EL Expressions
Table 9-1 contains example EL expressions and the result of evaluating them.
Table 9-1 Example Expressions
EL Expression |
Result |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[1,3,5,2].stream().sorted().toList() |
|
|
|
|
The context path |
|
The value of the |
|
The value of the request parameter named
|
|
The host |
|
The value of the entry named |
|
The value of the request-scoped attribute named
|
|
Gets the value of the property |
|
The return value of the method |
4.5. Using Jakarta Server Faces Technology in Web Pages
Web pages (Facelets pages, in most cases) represent the presentation layer for web applications. The process of creating web pages for a Jakarta Server Faces application includes using component tags to add components to the page and wire them to backing beans, validators, listeners, converters, and other server-side objects that are associated with the page.
This chapter explains how to create web pages using various types of component and core tags. In the next chapter, you will learn about adding converters, validators, and listeners to component tags to provide additional functionality to components.
Many of the examples in this chapter are taken from Chapter 60, "Duke’s Bookstore Case Study Example."
4.5.1. Setting Up a Page
A typical Jakarta Server Faces web page includes the following elements:
-
A set of namespace declarations that declare the Jakarta Server Faces tag libraries
-
Optionally, the HTML head (
h:head
) and body (h:body
) tags -
A form tag (
h:form
) that represents the user input components
To add the Jakarta Server Faces components to your web page, you need to provide the page access to the two standard tag libraries: the Jakarta Server Faces HTML render kit tag library and the Jakarta Server Faces core tag library. The oJakarta Server Faces standard HTML tag library defines tags that represent common HTML user interface components. The Jakarta Server Faces core tag library defines tags that perform core actions and are independent of a particular render kit.
For a complete list of Jakarta Server Faces Facelets tags and their attributes, refer to the oJakarta Server Faces Facelets Tag Library documentation.
To use any of the Jakarta Server Faces tags, you need to include appropriate directives at the top of each page specifying the tag libraries.
For Facelets applications, the XML namespace directives uniquely identify the tag library URI and the tag prefix.
For example, when you create a Facelets XHTML page, include namespace directives as follows:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
The XML namespace URI identifies the tag library location, and the
prefix value is used to distinguish the tags belonging to that specific
tag library. You can also use other prefixes instead of the standard h
or f
. However, when including the tag in the page you must use the
prefix that you have chosen for the tag library. For example, in the
following web page the form
tag must be referenced using the h
prefix because the preceding tag library directive uses the h
prefix
to distinguish the tags defined in the HTML tag library:
<h:form ...>
The sections Adding Components to a Page Using HTML Tag Library Tags and Using Core Tags describe how to use the component tags from the Jakarta Server Faces standard HTML tag library and the core tags from the Jakarta Server Faces core tag library.
4.5.2. Adding Components to a Page Using HTML Tag Library Tags
The tags defined by the Jakarta Server Faces standard HTML tag library represent HTML form components and other basic HTML elements. These components display data or accept data from the user. This data is collected as part of a form and is submitted to the server, usually when the user clicks a button. This section explains how to use each of the component tags shown in Table 10-1.
Table 10-1 The Component Tags
Tag |
Functions |
Rendered As |
Appearance |
|
Represents a column of data in a data component |
A column of data in an HTML table |
A column in a table |
|
Submits a form to the application |
An HTML
|
A button |
|
Links to another page or location on a page |
An HTML
|
A link |
|
Represents a data wrapper |
An HTML |
A table that can be updated dynamically |
|
Represents an input form (inner tags of the form receive the data that will be submitted with the form) |
An HTML |
No appearance |
|
Displays an image |
An HTML |
An image |
|
Allows a user to upload a file |
An HTML
|
A field with a Browse… button |
|
Allows a page author to include a hidden variable in a page |
An HTML |
No appearance |
|
Allows a user to input a string without the actual string appearing in the field |
An HTML |
A field that displays a row of characters instead of the actual string entered |
|
Allows a user to input a string |
An HTML
|
A field |
|
Allows a user to enter a multiline string |
An HTML
|
A multirow field |
|
Displays a localized message |
An HTML |
A text string |
|
Displays localized messages |
A set of HTML |
A text string |
|
Displays a formatted message |
Plain text |
Plain text |
|
Displays a nested component as a label for a specified input field |
An HTML |
Plain text |
|
Links to another page or location on a page without generating an action event |
An HTML |
A link |
|
Displays a line of text |
Plain text |
Plain text |
|
Displays a table |
An HTML |
A table |
|
Groups a set of components under one parent |
A HTML
|
A row in a table |
|
Allows a user to change the value of a Boolean choice |
An HTML |
A check box |
|
Displays a set of check boxes from which the user can select multiple values |
A set of HTML |
A group of check boxes |
|
Allows a user to select multiple items from a set of items all displayed at once |
An HTML |
A box |
|
Allows a user to select multiple items from a set of items |
An HTML |
A menu |
|
Allows a user to select one item from a set of items all displayed at once |
An HTML |
A box |
|
Allows a user to select one item from a set of items |
An HTML |
A menu |
|
Allows a user to select one item from a set of items |
An HTML |
A group of options For a standalone radio button, use the |
The tags correspond to components in the javax.faces.component
package. The components are discussed in more detail in
Chapter 12, "Developing with Jakarta Server Faces
Technology."
The next section explains the important attributes that are common to most component tags. For each of the components discussed in the following sections, Writing Bean Properties explains how to write a bean property bound to that particular component or its value.
For reference information about the tags and their attributes, see the oJakarta Server Faces Facelets Tag Library documentation.
4.5.2.1. Common Component Tag Attributes
Most of the component tags support the attributes shown in Table 10-2.
Table 10-2 Common Component Tag Attributes
Attribute |
Description |
|
Identifies a bean property and binds the component instance to it. |
|
Uniquely identifies the component. |
|
If set to |
|
Specifies a condition under which the component should be rendered. If the condition is not satisfied, the component is not rendered. |
|
Specifies a Cascading Style Sheet (CSS) style for the tag. |
|
Specifies a CSS class that contains definitions of the styles. |
|
Specifies the value of the component in the form of a value expression. |
All the tag attributes except id
can accept expressions, as defined by
the EL, described in Expression Language.
An attribute such as rendered
or value
can be set on the page and
then modified in the backing bean for the page.
The id Attribute
The id
attribute is not usually required for a component tag but is
used when another component or a server-side class must refer to the
component. If you don’t include an id
attribute, the Jakarta Server Faces
implementation automatically generates a component ID. Unlike most other
Jakarta Server Faces tag attributes, the id
attribute takes expressions
using only the evaluation syntax described in
Immediate Evaluation, which uses the ${}
delimiters. For more information on expression syntax, see
Value Expressions.
The immediate Attribute
Input components and command components (those that implement the
ActionSource
interface, such as buttons and links) can set the
immediate
attribute to true
to force events, validations, and
conversions to be processed when request parameter values are applied.
You need to carefully consider how the combination of an input
component’s immediate
value and a command component’s immediate
value determines what happens when the command component is activated.
Suppose that you have a page with a button and a field for entering the
quantity of a book in a shopping cart. If the immediate
attributes of
both the button and the field are set to true
, the new value entered
in the field will be available for any processing associated with the
event that is generated when the button is clicked. The event associated
with the button as well as the events, validation, and conversion
associated with the field are all handled when request parameter values
are applied.
If the button’s immediate
attribute is set to true
but the field’s
immediate
attribute is set to false
, the event associated with the
button is processed without updating the field’s local value to the
model layer. The reason is that any events, conversion, and validation
associated with the field occur after request parameter values are
applied.
The bookshowcart.xhtml
page of the Duke’s Bookstore case study has
examples of components using the immediate
attribute to control which
component’s data is updated when certain buttons are clicked. The
quantity
field for each book does not set the immediate
attribute,
so the value is false
(the default).
<h:inputText id="quantity"
size="4"
value="#{item.quantity}"
title="#{bundle.ItemQuantity}">
<f:validateLongRange minimum="0"/>
...
</h:inputText>
The immediate
attribute of the Continue Shopping hyperlink is set to
true
, while the immediate
attribute of the Update Quantities
hyperlink is set to false
:
<h:commandLink id="continue"
action="bookcatalog"
immediate="true">
<h:outputText value="#{bundle.ContinueShopping}"/>
</h:commandLink>
...
<h:commandLink id="update"
action="#{showcart.update}"
immediate="false">
<h:outputText value="#{bundle.UpdateQuantities}"/>
</h:commandLink>
If you click the Continue Shopping hyperlink, none of the changes
entered into the quantity
input fields will be processed. If you click
the Update Quantities hyperlink, the values in the quantity
fields
will be updated in the shopping cart.
The rendered Attribute
A component tag uses a Boolean EL expression along with the rendered
attribute to determine whether the component will be rendered. For
example, the commandLink
component in the following section of a page
is not rendered if the cart contains no items:
<h:commandLink id="check" ... rendered="#{cart.numberOfItems > 0}">
<h:outputText value="#{bundle.CartCheck}"/>
</h:commandLink>
Unlike nearly every other Jakarta Server Faces tag attribute, the rendered
attribute is restricted to using rvalue expressions. As explained in
Value and Method Expressions, these rvalue
expressions can only read data; they cannot write the data back to the
data source. Therefore, expressions used with rendered
attributes can
use the arithmetic operators and literals that rvalue expressions can
use but lvalue expressions cannot use. For example, the expression in
the preceding example uses the >
operator.
Note: In this example and others, |
The style and styleClass Attributes
The style
and styleClass
attributes allow you to specify CSS styles
for the rendered output of your tags. Displaying Error
Messages with the h:message and h:messages Tags describes an example of
using the style
attribute to specify styles directly in the attribute.
A component tag can instead refer to a CSS class.
The following example shows the use of a dataTable
tag that references
the style class list-background
:
<h:dataTable id="items"
...
styleClass="list-background"
value="#{cart.items}"
var="book">
The style sheet that defines this class is stylesheet.css
, which will
be included in the application. For more information on defining styles,
see the Cascading Style Sheets specifications and drafts at
http://www.w3.org/Style/CSS/
.
The value and binding Attributes
A tag representing an output component uses the value
and binding
attributes to bind its component’s value or instance, respectively, to a
data object. The value
attribute is used more commonly than the
binding
attribute, and examples appear throughout this chapter. For
more information on these attributes, see
Creating a Managed Bean,
Writing Properties Bound to Component
Values, and Writing Properties Bound to
Component Instances.
4.5.2.2. Adding HTML Head and Body Tags
The HTML head (h:head
) and body (h:body
) tags add HTML page
structure to Jakarta Server Faces web pages.
-
The
h:head
tag represents the head element of an HTML page. -
The
h:body
tag represents the body element of an HTML page.
The following is an example of an XHTML page using the usual head and body markup tags:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Add a title</title>
</head>
<body>
Add Content
</body>
</html>
The following is an example of an XHTML page using h:head
and h:body
tags:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head>
Add a title
</h:head>
<h:body>
Add Content
</h:body>
</html>
Both of the preceding example code segments render the same HTML elements. The head and body tags are useful mainly for resource relocation. For more information on resource relocation, see Resource Relocation Using h:outputScript and h:outputStylesheet Tags.
4.5.2.3. Adding a Form Component
An h:form
tag represents an input form, which includes child
components that can contain data that is either presented to the user or
submitted with the form.
Figure 10-1 shows a typical login form in which a user enters a user name and password, then submits the form by clicking the Login button.
The h:form
tag represents the form on the page and encloses all the
components that display or collect data from the user, as shown here:
<h:form>
... other Jakarta Server Faces tags and other content...
</h:form>
The h:form
tag can also include HTML markup to lay out the components
on the page. Note that the h:form
tag itself does not perform any
layout; its purpose is to collect data and to declare attributes that
can be used by other components in the form.
A page can include multiple h:form
tags, but only the values from the
form submitted by the user will be included in the postback request.
4.5.2.4. Using Text Components
Text components allow users to view and edit text in web applications. The basic types of text components are as follows:
-
Label, which displays read-only text
-
Field, which allows users to enter text (on one or more lines), often to be submitted as part of a form
-
Password field, which is a type of field that displays a set of characters, such as asterisks, instead of the password text that the user enters
Figure 10-2 shows examples of these text components.
Text components can be categorized as either input or output. A Jakarta Server Faces output component, such as a label, is rendered as read-only text. A Jakarta Server Faces input component, such as a field, is rendered as editable text.
The input and output components can each be rendered in various ways to display more specialized text.
Table 10-3 lists the tags that represent the input components.
Table 10-3 Input Tags
Tag |
Function |
|
Allows a page author to include a hidden variable in a page |
|
The standard password field: accepts one line of text with no spaces and displays it as a set of asterisks as it is entered |
|
The standard field: accepts a one-line text string |
|
The standard multiline field: accepts multiple lines of text |
The input tags support the tag attributes shown in Table 10-4 in addition to those described in Common Component Tag Attributes. Note that this table does not include all the attributes supported by the input tags but just those that are used most often. For the complete list of attributes, refer to the oJakarta Server Faces Facelets Tag Library documentation.
Table 10-4 Input Tag Attributes
Attribute |
Description |
|
Identifies a converter that will be used to convert the component’s local data. See Using the Standard Converters for more information on how to use this attribute. |
|
Specifies an error message to display when the converter registered on the component fails. |
|
Specifies the direction of the text displayed by this component.
Acceptable values are |
|
Specifies a name that can be used to identify this component in error messages. |
|
Specifies the code for the language used in the rendered
markup, such as |
|
Takes a |
|
Specifies an error message to display when the user does not enter a value into the component. |
|
Identifies a method expression pointing to a managed bean
method that performs validation on the component’s data. See
Referencing a Method That Performs
Validation for an example of using the |
|
Specifies an error message to display when the validator registered on the component fails to validate the component’s local value. |
|
Identifies a method expression that points to a
managed bean method that handles the event of entering a value in this
component. See Referencing a Method That
Handles a Value-Change Event for an example of using
|
Table 10-5 lists the tags that represent the output components.
Table 10-5 Output Tags
Tag |
Function |
|
Displays a formatted message |
|
The standard read-only label: displays a component as a label for a specified input field |
|
Displays an |
|
Displays a one-line text string |
The output tags support the converter
tag attribute in addition to
those listed in Common Component Tag Attributes.
The rest of this section explains how to use some of the tags listed in Output Tags. The other tags are written in a similar way.
Rendering a Field with the h:inputText Tag
The h:inputText
tag is used to display a field. A similar tag, the
h:outputText
tag, displays a read-only, single-line string. This
section shows you how to use the h:inputText
tag. The h:outputText
tag is written in a similar way.
Here is an example of an h:inputText
tag:
<h:inputText id="name"
label="Customer Name"
size="30"
value="#{cashierBean.name}"
required="true"
requiredMessage="#{bundle.ReqCustomerName}">
<f:valueChangeListener
type="ee.jakarta.tutorial.dukesbookstore.listeners.NameChanged" />
</h:inputText>
The label
attribute specifies a user-friendly name that will be used
in the substitution parameters of error messages displayed for this
component.
The value
attribute refers to the name
property of a managed bean
named CashierBean
. This property holds the data for the name
component. After the user submits the form, the value of the name
property in CashierBean
will be set to the text entered in the field
corresponding to this tag.
The required
attribute causes the page to reload, displaying errors,
if the user does not enter a value in the name
field. The Jakarta Server
Faces implementation checks whether the value of the component is null
or is an empty string.
If your component must have a non-null value or a String
value at
least one character in length, you should add a required
attribute to
your tag and set its value to true
. If your tag has a required
attribute that is set to true
and the value is null or a zero-length
string, no other validators that are registered on the tag are called.
If your tag does not have a required
attribute set to true
, other
validators that are registered on the tag are called, but those
validators must handle the possibility of a null or zero-length string.
See Validating Null and Empty Strings
for more information.
Rendering a Password Field with the h:inputSecret Tag
The h:inputSecret
tag renders an <input type="password">
HTML tag.
When the user types a string into this field, a row of asterisks is
displayed instead of the text entered by the user. Here is an example:
<h:inputSecret redisplay="false" value="#{loginBean.password}" />
In this example, the redisplay
attribute is set to false
. This will
prevent the password from being displayed in a query string or in the
source file of the resulting HTML page.
Rendering a Label with the h:outputLabel Tag
The h:outputLabel
tag is used to attach a label to a specified input
field for the purpose of making it accessible. The following page uses
an h:outputLabel
tag to render the label of a check box:
<h:selectBooleanCheckbox id="fanClub"
rendered="false"
binding="#{cashierBean.specialOffer}" />
<h:outputLabel for="fanClub"
rendered="false
binding="#{cashierBean.specialOfferText}">
<h:outputText id="fanClubLabel"
value="#{bundle.DukeFanClub}" />
</h:outputLabel>
...
The h:selectBooleanCheckbox
tag and the h:outputLabel
tag have
rendered
attributes that are set to false
on the page but are set to
true in the CashierBean
under certain circumstances. The for
attribute of the h:outputLabel
tag maps to the id
of the input field
to which the label is attached. The h:outputText
tag nested inside the
h:outputLabel
tag represents the label component. The value
attribute on the h:outputText
tag indicates the text that is displayed
next to the input field.
Instead of using an h:outputText
tag for the text displayed as a
label, you can simply use the h:outputLabel
tag’s value
attribute.
The following code snippet shows what the previous code snippet would
look like if it used the value
attribute of the h:outputLabel
tag to
specify the text of the label:
<h:selectBooleanCheckbox id="fanClub"
rendered="false"
binding="#{cashierBean.specialOffer}" />
<h:outputLabel for="fanClub"
rendered="false"
binding="#{cashierBean.specialOfferText}"
value="#{bundle.DukeFanClub}" />
</h:outputLabel>
...
Rendering a Link with the h:outputLink Tag
The h:outputLink
tag is used to render a link that, when clicked,
loads another page but does not generate an action event. You should use
this tag instead of the h:commandLink
tag if you always want the URL
specified by the h:outputLink
tag’s value
attribute to open and do
not want any processing to be performed when the user clicks the link.
Here is an example:
<h:outputLink value="javadocs">
Documentation for this demo
</h:outputLink>
The text in the body of the h:outputLink
tag identifies the text that
the user clicks to get to the next page.
Displaying a Formatted Message with the h:outputFormat Tag
The h:outputFormat
tag allows display of concatenated messages as a
MessageFormat
pattern, as described in the API documentation for
java.text.MessageFormat
. Here is an example of an h:outputFormat
tag:
<h:outputFormat value="Hello, {0}!">
<f:param value="#{hello.name}"/>
</h:outputFormat>
The value
attribute specifies the MessageFormat
pattern. The
f:param
tag specifies the substitution parameters for the message. The
value of the parameter replaces the {0}
in the sentence. If the value
of "#{hello.name}"
is "Bill", the message displayed in the page is as
follows:
Hello, Bill!
An h:outputFormat
tag can include more than one f:param
tag for
those messages that have more than one parameter that must be
concatenated into the message. If you have more than one parameter for
one message, make sure that you put the f:param
tags in the proper
order so that the data is inserted in the correct place in the message.
Here is the preceding example modified with an additional parameter:
<h:outputFormat value="Hello, {0}! You are visitor number {1} to the page.">
<f:param value="#{hello.name}" />
<f:param value="#{bean.numVisitor}"/>
</h:outputFormat>
The value of {1}
is replaced by the second parameter. The parameter is
an EL expression, bean.numVisitor
, in which the property numVisitor
of the managed bean bean
keeps track of visitors to the page. This is
an example of a value-expression-enabled tag attribute accepting an EL
expression. The message displayed in the page is now as follows:
Hello, Bill! You are visitor number 10 to the page.
4.5.2.5. Using Command Component Tags for Performing Actions and Navigation
In Jakarta Server Faces applications, the button and link component tags are used to perform actions, such as submitting a form, and for navigating to another page. These tags are called command component tags because they perform an action when activated.
The h:commandButton
tag is rendered as a button. The h:commandLink
tag is rendered as a link.
In addition to the tag attributes listed in Common Component
Tag Attributes, the h:commandButton
and h:commandLink
tags can use
the following attributes.
-
action
, which is either a logical outcomeString
or a method expression pointing to a bean method that returns a logical outcomeString
. In either case, the logical outcomeString
is used to determine what page to access when the command component tag is activated. -
actionListener
, which is a method expression pointing to a bean method that processes an action event fired by the command component tag.
See Referencing a Method That Performs
Navigation for more information on using the action
attribute. See
Referencing a Method That Handles an
Action Event for details on using the actionListener
attribute.
Rendering a Button with the h:commandButton Tag
If you are using an h:commandButton
component tag, the data from the
current page is processed when a user clicks the button, and the next
page is opened. Here is an example of the h:commandButton
tag:
<h:commandButton value="Submit"
action="#{cashierBean.submit}"/>
Clicking the button will cause the submit
method of CashierBean
to
be invoked because the action
attribute references this method. The
submit
method performs some processing and returns a logical outcome.
The value
attribute of the example h:commandButton
tag references
the button’s label. For information on how to use the action
attribute, see Referencing a Method That
Performs Navigation.
Rendering a Link with the h:commandLink Tag
The h:commandLink
tag represents an HTML link and is rendered as an
HTML <a>
element.
An h:commandLink
tag must include a nested h:outputText
tag, which
represents the text that the user clicks to generate the event. Here is
an example:
<h:commandLink id="Duke" action="bookstore">
<f:actionListener
type="ee.jakarta.tutorial.dukesbookstore.listeners.LinkBookChangeListener" />
<h:outputText value="#{bundle.Book201}"/>
/h:commandLink>
This tag will render HTML that looks something like the following:
<a id="_idt16:Duke" href="#"
onclick="mojarra.jsfcljs(document.getElementById('j_idt16'),
{'j_idt16:Duke':'j_idt16:Duke'},'');
return false;">My Early Years: Growing Up on Star7, by Duke</a>
Note: The |
4.5.2.6. Adding Graphics and Images with the h:graphicImage Tag
In a Jakarta Server Faces application, use the h:graphicImage
tag to
render an image on a page:
<h:graphicImage id="mapImage" url="/resources/images/book_all.jpg"/>
In this example, the url
attribute specifies the path to the image.
The URL of the example tag begins with a slash (/
), which adds the
relative context path of the web application to the beginning of the
path to the image.
Alternatively, you can use the facility described in Web Resources to point to the image location. Here are two examples:
<h:graphicImage id="mapImage"
name="book_all.jpg"
library="images"
alt="#{bundle.ChooseBook}"
usemap="#bookMap" />
<h:graphicImage value="#{resource['images:wave.med.gif']}"/>
You can use similar syntax to refer to an image in a style sheet. The
following syntax in a style sheet specifies that the image is to be
found at resources/img/top-background.jpg
:
header {
position: relative;
height: 150px;
background: #fff url(#{resource['img:top-background.jpg']}) repeat-x;
...
4.5.2.7. Laying Out Components with the h:panelGrid and h:panelGroup Tags
In a Jakarta Server Faces application, you use a panel as a layout container for a set of other components. A panel is rendered as an HTML table. Table 10-6 lists the tags used to create panels.
Table 10-6 Panel Component Tags
Tag |
Attributes |
Function |
|
|
Displays a table |
|
|
Groups a set of components under one parent |
The h:panelGrid
tag is used to represent an entire table. The
h:panelGroup
tag is used to represent rows in a table. Other tags are
used to represent individual cells in the rows.
The columns
attribute defines how to group the data in the table and
therefore is required if you want your table to have more than one
column. The h:panelGrid
tag also has a set of optional attributes that
specify CSS classes: columnClasses
, footerClass
, headerClass
,
panelClass
, and rowClasses
. The role
attribute can have the value
"presentation"
to indicate that the purpose of the table is to format
the display rather than to show data.
If the headerClass
attribute value is specified, the h:panelGrid
tag
must have a header as its first child. Similarly, if a footerClass
attribute value is specified, the h:panelGrid
tag must have a footer
as its last child.
Here is an example:
<h:panelGrid columns="2"
headerClass="list-header"
styleClass="list-background"
rowClasses="list-row-even, list-row-odd"
summary="#{bundle.CustomerInfo}"
title="#{bundle.Checkout}"
role="presentation">
<f:facet name="header">
<h:outputText value="#{bundle.Checkout}"/>
</f:facet>
<h:outputLabel for="name" value="#{bundle.Name}" />
<h:inputText id="name" size="30"
value="#{cashierBean.name}"
required="true"
requiredMessage="#{bundle.ReqCustomerName}">
<f:valueChangeListener
type="ee.jakarta.tutorial.dukesbookstore.listeners.NameChanged" />
</h:inputText>
<h:message styleClass="error-message" for="name"/>
<h:outputLabel for="ccno" value="#{bundle.CCNumber}"/>
<h:inputText id="ccno"
size="19"
converterMessage="#{bundle.CreditMessage}"
required="true"
requiredMessage="#{bundle.ReqCreditCard}">
<f:converter converterId="ccno"/>
<f:validateRegex
pattern="\d{16}|\d{4} \d{4} \d{4} \d{4}|\d{4}-\d{4}-\d{4}-\d{4}" />
</h:inputText>
<h:message styleClass="error-message" for="ccno"/>
...
</h:panelGrid>
The preceding h:panelGrid
tag is rendered as a table that contains
components in which a customer inputs personal information. This
h:panelGrid
tag uses style sheet classes to format the table. The
following code shows the list-header
definition:
.list-header {
background-color: #ffffff;
color: #000000;
text-align: center;
}
Because the h:panelGrid
tag specifies a headerClass
, the
h:panelGrid
tag must contain a header. The example h:panelGrid
tag
uses an f:facet
tag for the header. Facets can have only one child, so
an h:panelGroup
tag is needed if you want to group more than one
component within an f:facet
. The example h:panelGrid
tag has only
one cell of data, so an h:panelGroup
tag is not needed. (For more
information about facets, see Using Data-Bound Table
Components.
The h:panelGroup
tag has an attribute, layout
, in addition to those
listed in Common Component Tag Attributes. If the layout
attribute has the value block
, an HTML div
element is rendered to
enclose the row; otherwise, an HTML span
element is rendered to
enclose the row. If you are specifying styles for the h:panelGroup
tag, you should set the layout
attribute to block
in order for the
styles to be applied to the components within the h:panelGroup
tag.
You should do this because styles, such as those that set width and
height, are not applied to inline elements, which is how content
enclosed by the span
element is defined.
An h:panelGroup
tag can also be used to encapsulate a nested tree of
components so that the tree of components appears as a single component
to the parent component.
Data, represented by the nested tags, is grouped into rows according to
the value of the columns
attribute of the h:panelGrid
tag. The
columns
attribute in the example is set to 2
, and therefore the
table will have two columns. The column in which each component is
displayed is determined by the order in which the component is listed on
the page modulo 2. So, if a component is the fifth one in the list of
components, that component will be in the 5 modulo 2 column, or column
1.
4.5.2.8. Displaying Components for Selecting One Value
Another commonly used component is one that allows a user to select one value, whether it is the only value available or one of a set of choices. The most common tags for this kind of component are as follows:
-
An
h:selectBooleanCheckbox
tag, displayed as a check box, which represents a Boolean state -
An
h:selectOneRadio
tag, displayed as a set of options -
An
h:selectOneMenu
tag, displayed as a scrollable list -
An
h:selectOneListbox
tag, displayed as an unscrollable list
Figure 10-3 shows examples of these components.
Displaying a Check Box Using the h:selectBooleanCheckbox Tag
The h:selectBooleanCheckbox
tag is the only tag that Jakarta Server Faces
technology provides for representing a Boolean state.
Here is an example that shows how to use the h:selectBooleanCheckbox
tag:
<h:selectBooleanCheckbox id="fanClub"
rendered="false"
binding="#{cashierBean.specialOffer}" />
<h:outputLabel for="fanClub"
rendered="false"
binding="#{cashierBean.specialOfferText}"
value="#{bundle.DukeFanClub}" />
The h:selectBooleanCheckbox
tag and the h:outputLabel
tag have
rendered
attributes that are set to false
on the page but are set to
true in the CashierBean
under certain circumstances. When the
h:selectBooleanCheckbox
tag is rendered, it displays a check box to
allow users to indicate whether they want to join the Duke Fan Club.
When the h:outputLabel
tag is rendered, it displays the label for the
check box. The label text is represented by the value
attribute.
Displaying a Menu Using the h:selectOneMenu Tag
A component that allows the user to select one value from a set of
values can be rendered as a box or a set of options. This section
describes the h:selectOneMenu
tag. The h:selectOneRadio
and
h:selectOneListbox
tags are used in a similar way. The
h:selectOneListbox
tag is similar to the h:selectOneMenu
tag except
that h:selectOneListbox
defines a size
attribute that determines how
many of the items are displayed at once.
The h:selectOneMenu
tag represents a component that contains a list of
items from which a user can select one item. This menu component is
sometimes known as a drop-down list or a combo box. The following code
snippet shows how the h:selectOneMenu
tag is used to allow the user to
select a shipping method:
<h:selectOneMenu id="shippingOption" required="true" value="#{cashierBean.shippingOption}">
<f:selectItem itemValue="2" itemLabel="#{bundle.QuickShip}"/>
<f:selectItem itemValue="5" itemLabel="#{bundle.NormalShip}"/>
<f:selectItem itemValue="7" itemLabel="#{bundle.SaverShip}"/>
</h:selectOneMenu>
The value
attribute of the h:selectOneMenu
tag maps to the property
that holds the currently selected item’s value. In this case, the value
is set by the backing bean. You are not required to provide a value for
the currently selected item. If you don’t provide a value, the browser
determines which one is selected.
Like the h:selectOneRadio
tag, the h:selectOneMenu
tag must contain
either an f:selectItems
tag or a set of f:selectItem
tags for
representing the items in the list. Using the f:selectItem
and f:selectItems Tags describes these tags.
4.5.2.9. Displaying Components for Selecting Multiple Values
In some cases, you need to allow your users to select multiple values rather than just one value from a list of choices. You can do this using one of the following component tags:
-
An
h:selectManyCheckbox
tag, displayed as a set of check boxes -
An
h:selectManyMenu
tag, displayed as a menu -
An
h:selectManyListbox
tag, displayed as a box
Figure 10-4 shows examples of these components.
These tags allow the user to select zero or more values from a set of
values. This section explains the h:selectManyCheckbox
tag. The
h:selectManyListbox
and h:selectManyMenu
tags are used in a similar
way.
Unlike a menu, a list displays a subset of items in a box; a menu
displays only one item at a time when the user is not selecting the
menu. The size
attribute of the h:selectManyListbox
tag determines
the number of items displayed at one time. The box includes a scroll bar
for scrolling through any remaining items in the list.
The h:selectManyCheckbox
tag renders a group of check boxes, with each
check box representing one value that can be selected:
<h:selectManyCheckbox id="newslettercheckbox"
layout="pageDirection"
value="#{cashierBean.newsletters}">
<f:selectItems value="#{cashierBean.newsletterItems}"/>
</h:selectManyCheckbox>
The value
attribute of the h:selectManyCheckbox
tag identifies the
newsletters
property of the CashierBean
managed bean. This property
holds the values of the currently selected items from the set of check
boxes. You are not required to provide a value for the currently
selected items. If you don’t provide a value, the first item in the list
is selected by default. In the CashierBean
managed bean, this value is
instantiated to 0, so no items are selected by default.
The layout
attribute indicates how the set of check boxes is arranged
on the page. Because layout is set to pageDirection
, the check boxes
are arranged vertically. The default is lineDirection
, which aligns
the check boxes horizontally.
The h:selectManyCheckbox
tag must also contain a tag or set of tags
representing the set of check boxes. To represent a set of items, you
use the f:selectItems
tag. To represent each item individually, you
use the f:selectItem
tag. The following section explains these tags in
more detail.
4.5.2.10. Using the f:selectItem and f:selectItems Tags
The f:selectItem
and f:selectItems
tags represent components that
can be nested inside a component that allows you to select one or
multiple items. An f:selectItem
tag contains the value, label, and
description of a single item. An f:selectItems
tag contains the
values, labels, and descriptions of the entire list of items.
You can use either a set of f:selectItem
tags or a single
f:selectItems
tag within your component tag.
The advantages of using the f:selectItems
tag are as follows.
-
Items can be represented by using different data structures, including
Array
,Map
, andCollection
. The value of thef:selectItems
tag can represent even a generic collection of POJOs. -
Different lists can be concatenated into a single component, and the lists can be grouped within the component.
-
Values can be generated dynamically at runtime.
The advantages of using f:selectItem
are as follows.
-
Items in the list can be defined from the page.
-
Less code is needed in the backing bean for the
f:selectItem
properties.
The rest of this section shows you how to use the f:selectItems
and
f:selectItem
tags.
Using the f:selectItems Tag
The following example from Displaying Components for
Selecting Multiple Values shows how to use the h:selectManyCheckbox
tag:
<h:selectManyCheckbox id="newslettercheckbox"
layout="pageDirection"
value="#{cashierBean.newsletters}">
<f:selectItems value="#{cashierBean.newsletterItems}"/>
</h:selectManyCheckbox>
The value
attribute of the f:selectItems
tag is bound to the managed
bean property cashierBean.newsletterItems
. The individual SelectItem
objects are created programmatically in the managed bean.
See UISelectItems Properties for information on how to write a managed bean property for one of these tags.
Using the f:selectItem Tag
The f:selectItem
tag represents a single item in a list of items. Here
is the example from Displaying a Menu Using the
h:selectOneMenu Tag once again:
<h:selectOneMenu id="shippingOption"
required="true"
value="#{cashierBean.shippingOption}">
<f:selectItem itemValue="2"
itemLabel="#{bundle.QuickShip}"/>
<f:selectItem itemValue="5"
itemLabel="#{bundle.NormalShip}"/>
<f:selectItem itemValue="7"
itemLabel="#{bundle.SaverShip}"/>
</h:selectOneMenu>
The itemValue
attribute represents the value for the f:selectItem
tag. The itemLabel
attribute represents the String
that appears in
the list component on the page.
The itemValue
and itemLabel
attributes are value-binding enabled,
meaning that they can use value-binding expressions to refer to values
in external objects. These attributes can also define literal values, as
shown in the example h:selectOneMenu
tag.
4.5.2.11. Displaying the Results from Selection Components
If you display components that allow a user to select values, you may also want to display the result of the selection.
For example, you might want to thank a user who selected the checkbox to
join the Duke Fan Club, as described in Displaying a Check
Box Using the h:selectBooleanCheckbox Tag. Because the checkbox is
bound to the specialOffer
property of CashierBean
, a
UISelectBoolean
value, you can call the isSelected
method of the
property to determine whether to render a thank-you message:
<h:outputText value="#{bundle.DukeFanClubThanks}"
rendered="#{cashierBean.specialOffer.isSelected()}"/>
Similarly, you might want to acknowledge that a user subscribed to
newsletters using the h:selectManyCheckbox
tag, as described in
Displaying Components for Selecting Multiple Values. To do
so, you can retrieve the value of the newsletters
property, the
String
array that holds the selected items:
<h:outputText value="#{bundle.NewsletterThanks}"
rendered="#{!empty cashierBean.newsletters}"/>
<ul>
<ui:repeat value="#{cashierBean.newsletters}" var="nli">
<li><h:outputText value="#{nli}" /></li>
</ui:repeat>
</ul>
An introductory thank-you message is displayed only if the newsletters
array is not empty. Then a ui:repeat
tag, a simple way to show values
in a loop, displays the contents of the selected items in an itemized
list. (This tag is listed in Table 8-2.)
4.5.2.12. Using Data-Bound Table Components
Data-bound table components display relational data in a tabular format.
In a Jakarta Server Faces application, the h:dataTable
component tag
supports binding to a collection of data objects and displays the data
as an HTML table. The h:column
tag represents a column of data within
the table, iterating over each record in the data source, which is
displayed as a row. Here is an example:
<h:dataTable id="items"
captionClass="list-caption
columnClasses="list-column-center, list-column-left,
list-column-right, list-column-center"
footerClass="list-footer"
headerClass="list-header"
rowClasses="list-row-even, list-row-odd"
styleClass="list-background"
summary="#{bundle.ShoppingCart}"
value="#{cart.items}"
border="1"
var="item">
<h:column>
<f:facet name="header">
<h:outputText value="#{bundle.ItemQuantity}" />
</f:facet>
<h:inputText id="quantity"
size="4"
value="#{item.quantity}"
title="#{bundle.ItemQuantity}">
<f:validateLongRange minimum="1"/>
<f:valueChangeListener
type="ee.jakarta.tutorial.dukesbookstore.listeners.QuantityChanged"/>
</h:inputText>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="#{bundle.ItemTitle}"/>
</f:facet>
<h:commandLink action="#{showcart.details}">
<h:outputText value="#{item.item.title}"/>
</h:commandLink>
</h:column>
...
<f:facet name="footer"
<h:panelGroup>
<h:outputText value="#{bundle.Subtotal}"/>
<h:outputText value="#{cart.total}" />
<f:convertNumber currencySymbol="$" type="currency" />
</h:outputText>
</h:panelGroup>
</f:facet>
<f:facet name="caption">
<h:outputText value="#{bundle.Caption}"/>
</f:facet>
</h:dataTable>
The example h:dataTable
tag displays the books in the shopping cart as
well as the quantity of each book in the shopping cart, the prices, and
a set of buttons the user can click to remove books from the shopping
cart.
The h:column
tags represent columns of data in a data component. While
the data component is iterating over the rows of data, it processes the
column component associated with each h:column
tag for each row in the
table.
The h:dataTable
tag shown in the preceding code example iterates
through the list of books (cart.items
) in the shopping cart and
displays their titles, authors, and prices. Each time the h:dataTable
tag iterates through the list of books, it renders one cell in each
column.
The h:dataTable
and h:column
tags use facets to represent parts of
the table that are not repeated or updated. These parts include headers,
footers, and captions.
In the preceding example, h:column
tags include f:facet
tags for
representing column headers or footers. The h:column
tag allows you to
control the styles of these headers and footers by supporting the
headerClass
and footerClass
attributes. These attributes accept
space-separated lists of CSS classes, which will be applied to the
header and footer cells of the corresponding column in the rendered
table.
Facets can have only one child, so an h:panelGroup
tag is needed if
you want to group more than one component within an f:facet
. Because
the facet tag representing the footer includes more than one tag, the
h:panelGroup
tag is needed to group those tags. Finally, this
h:dataTable
tag includes an f:facet
tag with its name
attribute
set to caption
, causing a table caption to be rendered above the
table.
This table is a classic use case for a data component because the number of books might not be known to the application developer or the page author when that application is developed. The data component can dynamically adjust the number of rows of the table to accommodate the underlying data.
The value
attribute of an h:dataTable
tag references the data to be
included in the table. This data can take the form of any of the
following:
-
A list of beans
-
An array of beans
-
A single bean
-
A
javax.faces.model.DataModel
object -
A
java.sql.ResultSet
object -
A
javax.servlet.jsp.jstl.sql.Result
object -
A
javax.sql.RowSet
object
All data sources for data components have a DataModel
wrapper. Unless
you explicitly construct a DataModel
wrapper, the Jakarta Server Faces
implementation will create one around data of any of the other
acceptable types. See Writing Bean
Properties for more information on how to write properties for use with
a data component.
The var
attribute specifies a name that is used by the components
within the h:dataTable
tag as an alias to the data referenced in the
value
attribute of h:dataTable
.
In the example h:dataTable
tag, the value
attribute points to a list
of books. The var
attribute points to a single book in that list. As
the h:dataTable
tag iterates through the list, each reference to
item
points to the current book in the list.
The h:dataTable
tag also has the ability to display only a subset of
the underlying data. This feature is not shown in the preceding example.
To display a subset of the data, you use the optional first
and rows
attributes.
The first
attribute specifies the first row to be displayed. The
rows
attribute specifies the number of rows, starting with the first
row, to be displayed. For example, if you wanted to display records 2
through 10 of the underlying data, you would set first
to 2 and rows
to 9. When you display a subset of the data in your pages, you might
want to consider including a link or button that causes subsequent rows
to display when clicked. By default, both first
and rows
are set to
zero, and this causes all the rows of the underlying data to display.
Table 10-7 shows the optional attributes for the
h:dataTable
tag.
Table 10-7 Optional Attributes for the h:dataTable Tag
Attribute |
Defines Styles For |
|
Table caption |
|
All the columns |
|
Footer |
|
Header |
|
Rows |
|
The entire table |
Each of the attributes in Table 10-7 can specify more than
one style. If columnClasses
or rowClasses
specifies more than one
style, the styles are applied to the columns or rows in the order that
the styles are listed in the attribute. For example, if columnClasses
specifies styles list-column-center
and list-column-right
, and if
the table has two columns, the first column will have style
list-column-center
, and the second column will have style
list-column-right
.
If the style attribute specifies more styles than there are columns or rows, the remaining styles will be assigned to columns or rows starting from the first column or row. Similarly, if the style attribute specifies fewer styles than there are columns or rows, the remaining columns or rows will be assigned styles starting from the first style.
4.5.2.13. Displaying Error Messages with the h:message and h:messages Tags
The h:message
and h:messages
tags are used to display error messages
when conversion or validation fails. The h:message
tag displays error
messages related to a specific input component, whereas the h:messages
tag displays the error messages for the entire page.
Here is an example h:message
tag from the guessnumber-jsf
application:
<p>
<h:inputText id="userNo"
title="Type a number from 0 to 10:"
value="#{userNumberBean.userNumber}">
<f:validateLongRange minimum="#{userNumberBean.minimum}"
maximum="#{userNumberBean.maximum}"/>
</h:inputText>
<h:commandButton id="submit" value="Submit"
action="response"/>
</p>
<h:message showSummary="true" showDetail="false"
style="color: #d20005;
font-family: 'New Century Schoolbook', serif;
font-style: oblique;
text-decoration: overline"
id="errors1"
for="userNo"/>
The for
attribute refers to the ID of the component that generated the
error message. The error message is displayed at the same location that
the h:message
tag appears in the page. In this case, the error message
will appear below the Submit button.
The style
attribute allows you to specify the style of the text of the
message. In the example in this section, the text will be a shade of
red, New Century Schoolbook, serif font family, and oblique style, and a
line will appear over the text. The message and messages tags support
many other attributes for defining styles. For more information on these
attributes, refer to the oJakarta Server Faces Facelets Tag
Library documentation.
Another attribute supported by the h:messages
tag is the layout
attribute. Its default value is list
, which indicates that the
messages are displayed in a bullet list using the HTML ul
and li
elements. If you set the attribute value to table
, the messages will
be rendered in a table using the HTML table
element.
The preceding example shows a standard validator that is registered on
the input component. The message tag displays the error message that is
associated with this validator when the validator cannot validate the
input component’s value. In general, when you register a converter or
validator on a component, you are queueing the error messages associated
with the converter or validator on the component. The h:message
and
h:messages
tags display the appropriate error messages that are queued
on the component when the validators or converters registered on that
component fail to convert or validate the component’s value.
Standard error messages are provided with standard converters and standard validators. An application architect can override these standard messages and supply error messages for custom converters and validators by registering custom error messages with the application.
4.5.2.14. Creating Bookmarkable URLs with the h:button and h:link Tags
The ability to create bookmarkable URLs refers to the ability to generate links based on a specified navigation outcome and on component parameters.
In HTTP, most browsers by default send GET requests for URL retrieval
and POST requests for data processing. The GET requests can have query
parameters and can be cached, which is not advised for POST requests,
which send data to servers for processing. The other Jakarta Server Faces
tags capable of generating links use either simple GET requests, as in
the case of h:outputLink
, or POST requests, as in the case of
h:commandLink
or h:commandButton
tags. GET requests with query
parameters provide finer granularity to URL strings. These URLs are
created with one or more name=value
parameters appended to the simple
URL after a ?
character and separated by either &;
or &
strings.
To create a bookmarkable URL, use an h:link
or h:button
tag. Both of
these tags can generate a link based on the outcome
attribute of the
component. For example:
<h:link outcome="somepage" value="Message" />
The h:link
tag will generate a URL link that points to the
somepage.xhtml
file on the same server. The following sample HTML is
generated from the preceding tag, assuming that the application name is
simplebookmark
:
<a href="/simplebookmark/somepage.xhtml>Message</a>
This is a simple GET request that cannot pass any data from page to
page. To create more complex GET requests and utilize the complete
functionality of the h:link
tag, use view parameters.
4.5.2.15. Using View Parameters to Configure Bookmarkable URLs
To pass a parameter from one page to another, use the
includeViewParams
attribute in your h:link
tag and, in addition, use
an f:param
tag to specify the name and value to be passed. Here the
h:link
tag specifies the outcome page as personal.xhtml
and provides
a parameter named Result
whose value is a managed bean property:
<h:body>
<h:form>
<h:graphicImage url="#{resource['images:duke.waving.gif']}"
alt="Duke waving his hand"/>
<h2>Hello, #{hello.name}!</h2>
<p>I've made your
<h:link outcome="personal" value="personal greeting page!"
includeViewParams="true">
<f:param name="Result" value="#{hello.name}"/>
</h:link>
</p>
<h:commandButton id="back" value="Back" action="index" />
</h:form>
</h:body>
If the includeViewParams
attribute is set on the component, the view
parameters are added to the hyperlink. Therefore, the resulting URL will
look something like this if the value of hello.name
is Timmy
:
http://localhost:8080/bookmarks/personal.xhtml?Result=Timmy
On the outcome page, specify the core tags f:metadata
and
f:viewparam
as the source of parameters for configuring the URLs. View
parameters are declared as part of f:metadata
for a page, as shown in
the following example:
<f:metadata>
<f:viewParam name="Result" value="#{hello.name}"/>
</f:metadata>
This allows you to specify the bean property value on the page:
<h:outputText value="Howdy, #{hello.name}!" />
As a view parameter, the name also appears in the page’s URL. If you edit the URL, you change the output on the page.
Because the URL can be the result of various parameter values, the order of the URL creation has been predefined. The order in which the various parameter values are read is as follows:
-
Component
-
Navigation-case parameters
-
View parameters
4.5.2.16. The bookmarks Example Application
The bookmarks
example application modifies the hello1
application
described in A Web Module That Uses Jakarta Server
Faces Technology: The hello1 Example to use a bookmarkable URL that
uses view parameters.
Like hello1
, the application includes the Hello.java
managed bean,
an index.xhtml
page, and a response.xhtml
page. In addition, it
includes a personal.xhtml page
, to which a bookmarkable URL and view
parameters are passed from the response.xhtml
page, as described in
Using View Parameters to Configure Bookmarkable URLs.
You can use either NetBeans IDE or Maven to build, package, deploy, and
run the bookmarks
example. The source code for this example is in the
tut-install`/examples/web/jsf/bookmarks/` directory.
To Build, Package, and Deploy the bookmarks Example Using NetBeans IDE
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
From the File menu, choose Open Project.
-
In the Open Project dialog box, navigate to:
tut-install/examples/web/jsf
-
Select the
bookmarks
folder. -
Click Open Project.
-
In the Projects tab, right-click the
bookmarks
project and select Build.This option builds the example application and deploys it to your GlassFish Server instance.
To Build, Package, and Deploy the bookmarks Example Using Maven
-
Make sure that GlassFish Server has been started (see Starting and Stopping GlassFish Server).
-
In a terminal window, go to:
tut-install/examples/web/jsf/bookmarks/
-
Enter the following command:
mvn install
This command builds and packages the application into a WAR file,
bookmarks.war
, that is located in thetarget
directory. It then deploys the WAR file to your GlassFish Server instance.
To Run the bookmarks Example
-
Enter the following URL in your web browser:
http://localhost:8080/bookmarks
-
In the text field, enter a name and click Submit.
-
On the response page, move your mouse over the "personal greeting page" link to view the URL with the view parameter, then click the link.
The
personal.xhtml
page opens, displaying a greeting to the name you typed. -
In the URL field, modify the Result parameter value and press Return.
The name in the greeting changes to what you typed.
4.5.2.17. Resource Relocation Using h:outputScript and h:outputStylesheet Tags
Resource relocation refers to the ability of a Jakarta Server Faces application to specify the location where a resource can be rendered. Resource relocation can be defined with the following HTML tags:
-
h:outputScript
-
h:outputStylesheet
These tags have name
and target
attributes, which can be used to
define the render location. For a complete list of attributes for these
tags, see theoJakarta Server Faces Facelets Tag Library
documentation.
For the h:outputScript
tag, the name
and target
attributes define
where the output of a resource may appear. Here is an example:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head id="head">
<title>Resource Relocation</title>
</h:head>
<h:body id="body">
<h:form id="form">
<h:outputScript name="hello.js"/>
<h:outputStylesheet name="hello.css"/>
</h:form>
</h:body>
</html>
Because the target
attribute is not defined in the tags, the style
sheet hello.css
is rendered in the head element of the page, and the
hello.js
script is rendered in the body of the page.
Here is the HTML generated by the preceding code:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Resource Relocation</title>
<link type="text/css" rel="stylesheet"
href="/context-root/javax.faces.resource/hello.css"/>
</head>
<body>
<form id="form" name="form" method="post"
action="..." enctype="...">
<script type="text/javascript"
src="/context-root/javax.faces.resource/hello.js">
</script>
</form>
</body>
</html>
If you set the target
attribute for the h:outputScript
tag, the
incoming GET request provides the location parameter. Here is an
example:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://xmlns.jcp.org/jsf/html">
<h:head id="head">
<title>Resource Relocation</title>
</h:head>
<h:body id="body">
<h:form id="form">
<h:outputScript name="hello.js" target="#{param.location}"/>
<h:outputStylesheet name="hello.css"/>
</h:form>
</h:body>
</html>
In this case, if the incoming request does not provide a location
parameter, the default locations will still apply: The style sheet is
rendered in the head, and the script is rendered inline. However, if the
incoming request specifies the location parameter as the head, both the
style sheet and the script will be rendered in the head
element.
The HTML generated by the preceding code is as follows:
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Resource Relocation</title>
<link type="text/css" rel="stylesheet"
href="/context-root/javax.faces.resource/hello.css"/>
<script type="text/javascript"
src="/context-root/javax.faces.resource/hello.js">
</script>
</head>
<body>
<form id="form" name="form" method="post"
action="..." enctype="...">
</form>
</body>
</html>
Similarly, if the incoming request provides the location parameter as the body, the script will be rendered in the body element.
The preceding section describes simple uses for resource relocation. That feature can add even more functionality for the components and pages. A page author does not have to know the location of a resource or its placement.
By using a @ResourceDependency
annotation for the components,
component authors can define the resources for the component, such as a
style sheet and script. This allows the page authors freedom from
defining resource locations.
4.5.3. Using Core Tags
The tags included in the Jakarta Server Faces core tag library are used to perform core actions that are not performed by HTML tags.
Table 10-8 lists the event-handling core tags.
Table 10-8 Event-Handling Core Tags
Tag |
Function |
|
Adds an action listener to a parent component |
|
Adds a |
|
Registers a special action listener whose sole purpose is to push a value into a managed bean when a form is submitted |
|
Adds a value-change listener to a parent component |
Table 10-9 lists the data-conversion core tags.
Table 10-9 Data-Conversion Core Tags
Tag |
Function |
|
Adds an arbitrary converter to the parent component |
|
Adds a |
|
Adds a |
Table 10-10 lists the facet core tags.
Table 10-10 Facet Core Tags
Tag |
Function |
|
Adds a nested component that has a special relationship to its enclosing tag |
|
Registers a |
Table 10-11 lists the core tags that represent items in a list.
Table 10-11 Core Tags That Represent Items in a List
Tag |
Function |
|
Represents one item in a list of items |
|
Represents a set of items |
Table 10-12 lists the validator core tags.
Table 10-12 Validator Core Tags
Tag |
Function |
|
Adds a |
|
Adds a |
|
Adds a |
|
Adds a custom validator to a component |
|
Adds a |
|
Delegates the validation of a local value to a
|
|
Enforces the presence of a value in a component |
Table 10-13 lists the core tags that fall into other categories.
Table 10-13 Miscellaneous Core Tags
Tag Category |
Tag |
Function |
Attribute configuration |
|
Adds configurable attributes to a parent component |
Localization |
|
Specifies a |
Parameter substitution |
|
Substitutes parameters into a
|
Ajax |
|
Associates an Ajax action with a single component or a group of components based on placement |
Event |
|
Allows installing a |
WebSocket |
|
Allows server-side communications to be pushed to all instances of a socket containing the same channel name. |
These tags, which are used in conjunction with component tags, are explained in other sections of this tutorial.
Table 10-14 lists the sections that explain how to use specific core tags.
Table 10-14 Where the Core Tags Are Explained
Tags |
Where Explained |
Event-handling tags |
|
Data-conversion tags |
|
|
Using Data-Bound Table Components and Laying Out Components with the h:panelGrid and h:panelGroup Tags |
|
|
|
|
|
|
|
|
Validator tags |
|
|
|
|
4.6. Using Converters, Listeners, and Validators
The previous chapter described components and explained how to add them to a web page. This chapter provides information on adding more functionality to the components through converters, listeners, and validators.
-
Converters are used to convert data that is received from the input components. Converters allow an application to bring the strongly typed features of the Java programming language into the String-based world of HTTP servlet programming.
-
Listeners are used to listen to the events happening in the page and perform actions as defined.
-
Validators are used to validate the data that is received from the input components. Validators allow an application to express constraints on form input data to ensure that the necessary requirements are met before the input data is processed.
4.6.1. Using the Standard Converters
The Jakarta Server Faces implementation provides a set of Converter
implementations that you can use to convert component data. The purpose
of conversion is to take the String-based data coming in from the
Servlet API and convert it to strongly typed Java objects suitable for
the business domain. For more information on the conceptual details of
the conversion model, see Conversion Model.
The standard Converter
implementations are located in the
javax.faces.convert
package. Normally, converters are implicitly
assigned based on the type of the EL expression pointed to by the value
of the component. However, these converters can also be accessed by a
converter ID. Table 11-1 shows the converter classes and
their associated converter IDs.
Table 11-1 Converter Classes and Converter IDs
Class in the javax.faces.convert Package |
Converter ID |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A standard error message is associated with each of these converters. If
you have registered one of these converters onto a component on your
page and the converter is not able to convert the component’s value, the
converter’s error message will display on the page. For example, the
following error message appears if BigIntegerConverter
fails to
convert a value:
{0} must be a number consisting of one or more digits
In this case, the {0}
substitution parameter will be replaced with the
name of the input component on which the converter is registered.
Two of the standard converters (DateTimeConverter
and
NumberConverter
) have their own tags, which allow you to configure the
format of the component data using the tag attributes. For more
information about using DateTimeConverter
, see Using
DateTimeConverter. For more information about using NumberConverter
,
see Using NumberConverter. The following section explains
how to convert a component’s value, including how to register other
standard converters with a component.
4.6.1.1. Converting a Component’s Value
To use a particular converter to convert a component’s value, you need to register the converter onto the component. You can register any of the standard converters in one of the following ways.
-
Nest one of the standard converter tags inside the component’s tag. These tags are
f:convertDateTime
andf:convertNumber
, which are described in Using NumberConverter, respectively. -
Bind the value of the component to a managed bean property of the same type as the converter. This is the most common technique.
-
Refer to the converter from the component tag’s
converter
attribute, specifying the ID of the converter class. -
Nest an
f:converter
tag inside of the component tag, and use either thef:converter
tag’sconverterId
attribute or itsbinding
attribute to refer to the converter.
As an example of the second technique, if you want a component’s data to
be converted to an Integer
, you can simply bind the component’s value
to a managed bean property. Here is an example:
Integer age = 0;
public Integer getAge(){ return age;}
public void setAge(Integer age) {this.age = age;}
The data from the h:inputText
tag in the this example will be
converted to a java.lang.Integer
value. The Integer
type is a
supported type of NumberConverter
. If you don’t need to specify any
formatting instructions using the f:convertNumber
tag attributes, and
if one of the standard converters will suffice, you can simply reference
that converter by using the component tag’s converter
attribute.
You can also nest an f:converter
tag within the component tag and use
either the converter tag’s converterId
attribute or its binding
attribute to reference the converter.
The converterId
attribute must reference the converter’s ID. Here is
an example that uses one of the converter IDs listed in
Table 11-1:
<h:inputText value="#{loginBean.age}">
<f:converter converterId="javax.faces.Integer" />
</h:inputText>
Instead of using the converterId
attribute, the f:converter
tag can
use the binding
attribute. The binding
attribute must resolve to a
bean property that accepts and returns an appropriate Converter
instance.
You can also create custom converters and register them on components
using the f:converter
tag. For details, see
Creating and Using a Custom Converter.
4.6.1.2. Using DateTimeConverter
You can convert a component’s data to a java.util.Date
by nesting the
convertDateTime
tag inside the component tag. The convertDateTime
tag has several attributes that allow you to specify the format and type
of the data. Table 11-2 lists the attributes.
Here is a simple example of a convertDateTime
tag:
<h:outputText value="#{cashierBean.shipDate}">
<f:convertDateTime type="date" dateStyle="full" />
</h:outputText>
When binding the DateTimeConverter
to a component, ensure that the
managed bean property to which the component is bound is of type
java.util.Date
. In the preceding example, cashierBean.shipDate
must
be of type java.util.Date
.
The example tag can display the following output:
Saturday, September 21, 2013
You can also display the same date and time by using the following tag in which the date format is specified:
<h:outputText value="#{cashierBean.shipDate}">
<f:convertDateTime pattern="EEEEEEEE, MMM dd, yyyy" />
</h:outputText>
If you want to display the example date in Spanish, you can use the
locale
attribute:
<h:outputText value="#{cashierBean.shipDate}">
<f:convertDateTime dateStyle="full"
locale="es"
timeStyle="long" type="both" />
</h:outputText>
This tag would display the following output:
jueves 24 de octubre de 2013 15:07:04 GMT
Refer to the "Customizing Formats" lesson of the Java Tutorial at
http://docs.oracle.com/javase/tutorial/i18n/format/simpleDateFormat.html
for more information on how to format the output using the pattern
attribute of the convertDateTime
tag.
Table 11-2 Attributes for the f:convertDateTime Tag
Attribute |
Type |
Description |
|
|
Used to bind a converter to a managed bean property. |
|
|
Defines the format, as specified by
|
|
|
Used with composite components. Refers to one of the objects within the composite component inside which this tag is nested. |
|
|
|
|
|
Custom formatting pattern that determines how the date/time string
should be formatted and parsed. If this attribute is specified,
See Table 11-3 for the default values when |
|
|
Defines the format, as specified by
|
|
|
Time zone in which to interpret any
time information in the |
|
|
Specifies whether the string value will contain a date, a time, or both.
Valid values are: See Table 11-3 for additional information. |
Table 11-3 Type Attribute and Default Pattern Values
Type Attribute |
Class |
Default When Pattern Is Not Specified |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
4.6.1.3. Using NumberConverter
You can convert a component’s data to a java.lang.Number
by nesting
the convertNumber
tag inside the component tag. The convertNumber
tag has several attributes that allow you to specify the format and type
of the data. Table 11-4 lists the attributes.
The following example uses a convertNumber
tag to display the total
prices of the contents of a shopping cart:
<h:outputText value="#{cart.total}">
<f:convertNumber currencySymbol="$" type="currency"/>
</h:outputText>
When binding the NumberConverter
to a component, ensure that the
managed bean property to which the component is bound is of a primitive
type or has a type of java.lang.Number
. In the preceding example,
cart.total
is of type double
.
Here is an example of a number that this tag can display:
$934
This result can also be displayed by using the following tag in which the currency pattern is specified:
<h:outputText id="cartTotal" value="#{cart.total}">
<f:convertNumber pattern="$####" />
</h:outputText>
See the "Customizing Formats" lesson of the Java Tutorial at
http://docs.oracle.com/javase/tutorial/i18n/format/decimalFormat.html
for more information on how to format the output by using the pattern
attribute of the convertNumber
tag.
Table 11-4 Attributes for the f:convertNumber Tag
Attribute |
Type |
Description |
|
|
Used to bind a converter to a managed bean property. |
|
|
ISO 4217 currency code, used only when formatting currencies. |
|
|
Currency symbol, applied only when formatting currencies. |
|
|
Used with composite components. Refers to one of the objects within the composite component inside which this tag is nested. |
|
|
Specifies whether formatted output contains grouping separators. |
|
|
Specifies whether only the integer part of the value will be parsed. |
|
|
|
|
|
Maximum number of digits formatted in the fractional part of the output. |
|
|
Maximum number of digits formatted in the integer part of the output. |
|
|
Minimum number of digits formatted in the fractional part of the output. |
|
|
Minimum number of digits formatted in the integer part of the output. |
|
|
Custom formatting pattern that determines how the number string is formatted and parsed. |
|
|
Specifies whether the string value is parsed and
formatted as a |
4.6.2. Registering Listeners on Components
An application developer can implement listeners as classes or as
managed bean methods. If a listener is a managed bean method, the page
author references the method from either the component’s
valueChangeListener
attribute or its actionListener
attribute. If
the listener is a class, the page author can reference the listener from
either an f:valueChangeListener
tag or an f:actionListener
tag and
nest the tag inside the component tag to register the listener on the
component.
Referencing a Method That Handles an
Action Event and Referencing a Method
That Handles a Value-Change Event explain how a page author uses the
valueChangeListener
and actionListener
attributes to reference
managed bean methods that handle events.
This section explains how to register a NameChanged
value-change
listener and a BookChange
action listener implementation on
components. The Duke’s Bookstore case study includes both of these
listeners.
4.6.2.1. Registering a Value-Change Listener on a Component
A page author can register a ValueChangeListener
implementation on a
component that implements EditableValueHolder
by nesting an
f:valueChangeListener
tag within the component’s tag on the page. The
f:valueChangeListener
tag supports the attributes shown in
Table 11-5, one of which must be used.
Table 11-5 Attributes for the f:valueChangeListener Tag
Attribute |
Description |
|
References the fully qualified class name of a
|
|
References an object that implements |
The following example shows a value-change listener registered on a component:
<h:inputText id="name"
size="30"
value="#{cashierBean.name}"
required="true"
requiredMessage="#{bundle.ReqCustomerName}">
<f:valueChangeListener
type="ee.jakarta.tutorial.dukesbookstore.listeners.NameChanged" />
</h:inputText>
In the example, the core tag type
attribute specifies the custom
NameChanged
listener as the ValueChangeListener
implementation
registered on the name
component.
After this component tag is processed and local values have been
validated, its corresponding component instance will queue the
ValueChangeEvent
associated with the specified ValueChangeListener
to the component.
The binding
attribute is used to bind a ValueChangeList