Vous êtes sur la page 1sur 148

SUN TECHNOLOGIES: JAVA

ENTERPRISE EDITION

Loc ROBERT, SUN

http://www.supinfo.com

SUN TECHNOLOGIES: JAVA ENTERPRISE EDITION


by Loc ROBERT
DESCRIPTION_CURSUS
Discovery

of

Java

http://www.supinfo.com

Enterprise

Edition

Chapter 1. EJB 3.0


In this course, we'll see:

Understand EJB concepts

Setting up EJB inside your Java EE 5 application

Calling EJB from client applications

Sending messages between different applications

1. Course
1.1. Introduction
Do you need to set up distributed applications? Which more is, with a simple, powerful, and easily maintainable
architecture? EJB will certainly answer your waiting. Moreover, behind this name, there are several
technologies: one allowing managing the conversation on the network, another to supervise the data base... and
well of others still. The common point between them is that you externalize on an application server logic trade
of an application. Thus, as this part treated, you will have to write the "frontal" part of your application (see
architecture Java EE).

To help you to conceptualize this technology, we advise you to compare this technology with a brain, because
its the central place of the application. Lobes fill of the distinct functions: memories, reflexion, communication,
etc. the same way, there is EJB various parts which fill the different roles.

1.2. EJB Presentation


1.2.1. What does EJB mean?
Written in the programming Java language, an enterprise bean is a component on server side which
encapsulates logic part of an application. Logic part is the code which achieves the goal of the application. Let
us take the example of an application of inventory control, the enterprise beans could implement logic trade in
3
http://www.supinfo.com

methods called checkInventoryLevel() and orderProduct(). By calling upon these methods, the distant customers
can reach the services of inventory provided by the application.
As we will see at the time of EJB practical application, it is necessary to have an application server in order to
lodge an application based on EJB. Indeed, this one must provide many mechanisms making it possible to
manage the authorities of EJB, to make secure, share the application on a grid of calculation... etc.
At the moment, well base ourselves only on the specifications of EJB. The specifications are texts produced by
expert groups from companies like Sun, IBM, Oracle... etc, in order to define bases common to all application
servers.

1.2.2. EJB advantages


Well realize at the end of this essential that EJB make possible to separate the application layers in a clear way.
Indeed, the functionalities suggested fit in an organization of the effective project.
The separation of software in various parts makes it possible to understand what one is building:

What will be the complete picture

The responsibilities the subsystems and the developers

How to manage the growth of the system

Where the problems can appear?


To prepare with changes in the needs or the approaches of implementation:

Understand the limits of what you can really manage

Know what you would have to change or build to satisfy

Belong stable with the addition of new needs? ...


Moreover, EJB are components of very high level. That means that the concepts that we will see are very
powerful and are really simple to set up. Most of the time, the programmer will have only to take into account
the constraint trade of his project, and to configure simple classes by means of some annotations.
We will reuse without any reflection to account for the concepts like IO, RMI or JDBC, however, only the
application server will have to use these technologies.

1.2.3. When should you use EJB?


You should use the enterprise beans if your application must respect one of the following conditions:

The application must be easy to update. To adapt to an increasingly significant number of users, you can need
to distribute the components of an application through multiple machines. The enterprise beans of an
application can operate on various machines, but also their localization will remain transparent for the
customers

The application must be transactional. EJB support the transactions, the mechanisms which control the access
convergent to the shared objects
4
http://www.supinfo.com

The application will have different kinds of customers. With only some lines of code, the distant customers
can easily locate EJB. These customers can be light, various and numerous.

1.2.4. EJB types


The table below summarizes the three types of EJB:

Table 1.1. EJB Types


Type

Goal

Session

Carry out a task for a customer. Apply a service Web

Entity

Represent an entity which exists in persistent storage

Message

Acts like a listener for API Java Message Service,


treating the asynchronous messages

Timer

Allows to plan tasks at precise hours

Well have in this essential only about Beans of type Session, Message and Entity because they are usually used.
Those of Timer type will be seen in a more advanced course on EJB.

1.2.5. EJB3 changelog


Specification 3 of EJB was elaborate in order to simplify the model of design of EJB. Here are the principal
points which were simplified:

Simplification of the definition of the interfaces, suppression of a good number of necessary points in version
2.1 (more need to inherit a super interface or class)

Simplification for the creation of the class of Bean.

Simplification of API for the access to the environment of Bean: definition by simple dependent injection

Introduction of the use of the annotations as Java who are used in the place of the descriptor of deployment

Entity Beans are simple POJOs annotated. The mapping relational-object can be declared in the form of
annotations.
Entity beans have greatly been improved during its third version. The specification defines that a bean written
with API EJB3 must be able to be a client with a component writes with the API 2.1 (2 & 1 also). That has of
course like objective to facilitate the migration of the existing applications or simply the use of those in the new
applications.
Knowing that EJB version 3 go back to semi-2006, it acts of a still young technology, which begins only its
phase of adoption with industry. EJB 2 is still used even if that is not a doubt that they will migrate gradually
towards the new specifications.

1.3. Concepts
We will approach, in this part, the whole of EJB concepts. We will explain the various types of existing EJB but
also their differences and their uses.

1.3.1. EJB architecture


An EJB architecture is made up of at least 3-tiers: a customer (ex: Web, heavy customer...), applicative logic

5
http://www.supinfo.com

(EJBs) and a data base (ex: base relational, LDAP, ERP...).

In this architecture, EJB are located in the third "applicative logical". EJB implement logic trade of the
application (for the Session part) and represent an abstraction of the access to the data base (for the Entity part).
However, architecture EJB is before a whole evolutionary architecture. It is then possible to make evolve a
simple application EJB to an application directed Business To Business being connected towards other systems
of company.

In this architecture, EJB are located in the third "applicative logical". EJB implement logic trade of the
application (for the Session part) and represent an abstraction of the access to the data base (for the Entity part).
However, architecture EJB is before a whole evolutionary architecture. It is then possible to make evolve a
simple application EJB to an application directed Business To Business being connected towards other systems
of company.

The preceding diagram is the structure of an EJB server. Even if the container has the most important role, its
the server which switches the whole of the requests and manages the whole of the containers and services. The
server must manage, moreover, one whole of services of infrastructure common to the whole of the containers
or the services. The specification Java EE obliges the server to offer a service of directory JNDI and a service of
transaction. Of course, application servers generally provide other services as a data base integrated or the
security management. The goal is to facility the development, the deployment, etc... We can compare server
EJB as an orchestra. The role of this server is to be the leader. It is him which directs the whole of the services
and their cycle of life (starting, stop, pause...). Each part of the orchestra corresponds to a service (EJB,
Transaction, Base data...). They all are independent, but they work together to produce a common result.
1.3.1.1. EJB server
EJB server manages whole of the services systems for EJB, and also manages the containers which authorities
of EJB (called "beans") are carried out.
1.3.1.2. EJB container
A container, it is before all a "block box" which manages:

communication with the services of infrastructure

6
http://www.supinfo.com

applications and their cycle of life related to the customers


The container works of par with the server, providing, with them two, the environment of execution for EJB.
The container simplifies the life of the developer thanks to a reduction of the codes to be built, a simplification
of the treatments (automatic treatments), and a reduced maintenance (separation of the layers by levels of
abstraction). Indeed, the container is at the same time an application managing of the applications but also a tool
which generates code for each EJB.
It is also the container which will make it possible the developer to use the services of infrastructure available
within EJB server as connection to the database, the management of the transactions...

The main role of container EJB is, however, to manage the cycle of life of the applications EJB which are
associated for him. It is him which deploys them, stops them and redeploys them, while managing their
conformity with the specifications of the server. It also makes it possible to control the components which are
with its load.
Even if the container is the central point of the execution of EJB, the developers do not have to be worried
some; it is a "block box" which, according to the specification, is carried out according to certain well defined
events.
To continue the metaphor of the orchestra, the container is the person who prepares the instruments, the
partitions and the environment necessary to the musicians (represented by EJB).

1.3.2. What is a Session Bean?


A Bean Session is component an applicative side server making it possible to provide one or more services to
various customer applications. A service is useful, for example, to recover the list of the products of a shop, to
record a reservation or to check the validity of a stock. It can also represent a workflow. A Bean Session can be
regarded as a storyboard in the world of cinematographic animation: it defines the successive stages in order to
lead to a final objective.
The Beans Session thus constitutes bricks of logic trade of an application. They treat the data and carry out the
operations related to the logic of the company.
Beans Sessions are as "frontage" between the customers and the data. Whereas Entity Bean (explained in the
following chapter) is used to reach the data (addition, modification, suppression...).
Bean Sessions are divided into two types: "Stateless" and "Statefull".
1.3.2.1. State management
There are two types of session beans: stateless and statefull. The choice of the type Stateless or Statefull is based
on the interaction wished between the customer and the Bean Session.
1.3.2.1.1. Stateless session bean
Stateless Session Bean is a collection of services gathered around the same subject. Stateless means that the
service is autonomous in its execution and thus which it does not depend on a particular context. The important
point lies in the fact that no state is preserved between two invocations of methods. When a customer

7
http://www.supinfo.com

application calls a method of a Bean Session, this one carries out the method and turns over possibly the result.
The execution is not worried what could be made before or what could be made afterwards. This type of
execution is typically the same one as that of protocol HTTP (mode offline).
Stateless Session Beans tend to being general in order to be able to be re-used in other contexts. The advantage
of the Stateless type is its capacity to be gone up in load. Indeed, several customers use the same authority of
EJB in a concurrent way.

1.3.2.1.2. Stateful session bean


Statefull Session Bean is an extension of the customer application. It introduces the concept of session between
the customer and the server. One speaks precisely about conversational state to qualify this type of
communication. So a method called on EJB can read or modify information on the conversational state. EJB is
divided by all the methods for a single customer. Contrary to the Stateless type, Statefull Session Beans tend to
being specific to the application. The virtual caddie is the most common example to illustrate the use of Statefull
Session Bean.

In the case of Statefull, each customer is related to an authority of EJB (fig. 3.2). This type of Bean Session thus
consumes more memory that the Stateless type. Moreover, the work and the maintenance of association
constitute an important additional task for the container. It results from it a worse rise in load and sometimes
degradation from the performances when an application uses the Statefull type wrongly and without reason.
As we detailed at the beginning of this part, each authority of Statefull Session Bean is associated to a single
customer. This type of component maintains the state conversational with the customer, the variables of
authorities of this component are then related to the customer and their values preserved of a call of method at
another.
However, that doesnt mean that in any case that Statefull Session Bean is persistent. The server of application
can use a system of plug ("swap") for preoccupations with an optimization of memory (concept of passivation)
Statefull Session Bean is usually used to manage a process being carried out in several stages (purchases on a
going site, to reserve a travel, to send a newsletter...).
Let us take the example of a site of trade online. The basket can be modeled thanks to Statefull Session Bean. A
sale is carried out after several stages:

Choice of the articles

8
http://www.supinfo.com

Creation of a clients' account or use of an existing account

Choice of the payment of the order

Payment

Recording of the order


It is imperative to safeguard the state of the conversation between these various stages in order not to lose
information.

1.3.2.2. Access to the Session Bean


Beyond the simple delimitation of the various applicative layers, EJB define the way in which the various
announcers of year structures Java EE interact. They define, moreover, the possibilities offered to the various
customers (Java application, applet, application being carried out one the same server of applications) and the
methods of communication. Thus, it will possible to define EJB according to two prospective customers for the
customer: local sight (room) has and has distant sight (remote).
Beyond the simple delimitation of the various applicative layers, EJB define the way in which the various
speakers of architecture Java EE interact.
They define, moreover, the possibilities offered to the various customers (Java application, applet, application
being carried out on the same server of applications) and the methods of communication.
Thus, it will be possible to define EJB according to two prospects for the customer: a local sight (room) and a
distant sight (remote).
1.3.2.2.1. Local visibility
By adopting has local sight (room) for has EJB, any customer carried out in the same virtual machine (another
EJB, servlet ...) is whitebait to call the methods of this EJB. In this sight, the calls of method of EJB by the
customer are carried out have in any traditional Java application (Java SE). The arguments passed by possible
reference and it are, for the customer to directly modify the recovered objects. He results has weaker
demarcation from it from EJB with respect to his customers. Unfavorable its necessary then to consider that
various customers handle the same object At the same time and thus to anticipate the effects that that edge
induce.
One the other hand, the uses of has local sight makes it possible to optimize the performances of the server of
application and to minimize the resources. This one does not cuts then to Be occupied of specificities related to
transport via the network (not of serialization of the objects, No communication network...).
1.3.2.2.2. Remote visibility
By adopting a distant sight (remote), a EJB places at the disposal its methods with customers being carried out
on different virtual machines, and thus on different physical machines (applet, applications Java, etc...).
Within the framework of a distant sight, the demarcations are stronger between an EJB and its customer. The
calls of methods are done via technology RMI, the arguments and values of return must be serialized and are not
9
http://www.supinfo.com

transmitted any more by reference. It is then more possible only one customer modifies the same object of
another customer, and it is thus easier to delimit the various fields of safety.
On the other hand, the use of a distant sight has also disadvantages. The objects having to be "transportable"
remotely, the container owes serialize/unserialize these objects to transmit them via the network. It results from
it from the higher processing times compared to the local calls.
1.3.2.2.3. Web services visibility
The webservices are spread more and more on Internet, because they make it possible to use any service starting
from any language.
It is possible to specify the visibility of your EJB with the webservice type so that it can be used with the
manner of a webservice. However, this choice is restricted with EJB of the type Stateless Session Bean.
This technology misses maturity however and must for the moment to remain on the level of the concerns of
technological survey.
1.3.2.2.4. How to choose your connection?
The adoption of a local or distant sight decides at the time of the creation of EJB. It is completely possible
simultaneously to consider the use of these two sights, but it will be necessary to take into account the fact that
they are not completely equivalent (in particular on the level of safety with the passages by reference/valor).
The principal difference between these two types is undoubtedly the local access or the remote access. If the
customer application is carried out within the same virtual machine then the local sight certainly will be adapted
and conversely for the remote sight. The choice should not be generic, but must be made compared to the needs
for the application. It is however possible to support the local accesses while placing an intermediary (the
container Web) between EJB and the distant customer.
The sight webservice, as for it, is to be used when the customer is not written as Java or when you wish to
render your service most open possible. Typically, if you wish to give the possibility to your purchasers of
consulting your catalogue of products in any manner, it can be judicious to give them the access to such a Web
Service.
To compare this concept with an orchestra, the local side would be that of a spectator present in the room and
the remote side that of a spectator listening to on his radio the repeat broadcast placed at the disposal by the
orchestra. The side webservice would be that of an external TV channel, downloading the recording in the
complete concert, placed at the disposal by the orchestra (" Business to Business ").
1.3.2.3. When to use a Session Bean ?
Here some conditions concerning the use of the Beans Session in a system of company:

At any moment, only one customer has access to the authority of the Bean Session.

The state of Bean is not persistent, it exists only for one short duration (approximately a few hours).

The service can be accessible also via a service Web.


Statefull Session Beans are suitable if one of the following conditions (not exhaustive) is true:

The state of Bean represents the interaction between Bean and a particular customer.

Bean must store the information concerning the customer during the execution of the methods.

10
http://www.supinfo.com

Bean makes the connection between the customer and other components of the application, presenting a sight
simplified at the customer.

In slide, Bean controls the workflow of several Beans Company (it is thus a frontage).
To improve performances, you can choose to use Stateless Session Bean if it has one of these characteristics:

The state of Bean does not have a data specific to a customer.

In only one call of method, Bean achieves a generic task for all the customers. For example, to send an email
confirms an order on line.

Bean recovers of a data base a unit of data in reading alone which are often used by the customers. Such
Bean, for example, could recover the lines of a table which represent the products which are on sale this
month.
The choice of the type of Bean Session is not always obvious. However, in a large majority of the cases, the
services offered are static, i.e. independent of the customer who calls them. In such cases, prefer the Stateless
type by defect.

1.3.3. What is a Message Driven Bean?


1.3.3.1. Presentation
Within an information system of company, two applications can need to communicate. By communication, it is
necessary to include/understand a sending of data directly interpretable and usable by the other applications.
They are the Message Driven Beans which makes it possible to treat the messages coming from other
applications.
The concept of MDB (Message Driven Bean) was introduced with EJB 2.0 in order to treat the messages
coming from a supplier JMS (Java Message Service). Since version 2.1, the Beans Messages support any system
of transport and are thus independent of JMS. Specification EJB 3.0 does not offer really new functionality, but
largely simplifies the development of these components.
1.3.3.2. Send a message with JMS
All the compatible servers of application EJB 3.0 must support JMS. Many editors provide their own
implementation JMS, others provide the supports to question other implementations JMS. In all the cases, a
supplier JMS is inevitable to use the Bean Message.
JMS is the API one used for the access to a system of transport of company. It is the solution Java EE with the
concept of the MOM (Message Oriented Middleware).
This system allows the exchange of messages between various distant applications. The servers of transport are
often ignored (contrary to the database servers), although they are numerous. One finds MQSeries from IBM,
JBoss Messaging (in the past JBoss MQ), One Message Tail of Sun Microsystem... The applications using JMS
are independent of the type of server to which they are connected since they use the API JMS.
The applications generally use JMS in architectures of the type B2B (Business to Business). Indeed, this API
makes it possible to interconnect any system using the principle of transport where the sending and the reception
of message are asynchronous. That means that the applications communicating via JMS cannot be carried out at
the same time, on the same principle as the system of electronic mail (email). When the sender sends a request
(by an email), then it doesnt receive the answer directly. It may be that it never receives answer, or only one
acknowledgement of delivery.

11
http://www.supinfo.com

Architecture JMS is made up of various elements:

a supplier

consumer

messages

destinations
Thus, a supplieris the element has the load of the delivery of the messages between the various speakers. He
occupies himself of treating the sendings and making so that they are received.
A customer is an application or intervening component of application at the time of the exchanges. He sends or
receives the messages.
A message is, as its name indicates it, the element which will forward via a communication between the
customers. A supplier is always used as intermediary; one thus does not send them directly customer to another.
The destinations are objects configured on the level of the supplier which are at disposal of the customers and
who will be used by the latter for the sending and the reception of the messages. To schematize, one can say that
they are " letter boxes " in which the messages are placed while waiting for that a customer comes to claim
them.
1.3.3.3. When use it?
An important point in this architecture is that it allows a communication slightly coupled between the
customers: a customer is not worried identity of sound or his correspondents not of their possible state.
Moreover, this system can work in heterogeneous environment (C++ application, Java...).
1.3.3.4. Message transmission facility
JMS offers two models of transport: pointtopoint and publication/subscription. In a simple way, the pointtopoint
model represents a relation One to One between a message and a recipient whereas the model publication/
subscription is represented by a connection One to Many.
1.3.3.4.1. Peer to Peer (P2P)
The pointtopoint model makes it possible to connect the customer applications between them via a queue (tail).
It is exactly like the principle of a pile. The messages are sent and piled up. When a customer application
(consuming) is free, it then receives the piled up messages.

12
http://www.supinfo.com

In a pointtopoint model a message is transmitted only to only one application.


1.3.3.4.2. Publishion / Subscription
In this model, a producer can send a message to several consumers by the means of a subject (topic). Each
consumer must however have been registered beforehand on this subject if not it does not receive anything.

This model can be assimilated to a hub (material physique of network). Each new message is broadcast towards
each registered consumer. The producer is independent owing to the fact that the message was received by the
consumers.
There are two types of subscription: temporary and durable. In the temporary case, the consumers receive the
messages as long as they are connected to the subject. In the case of a durable subscription, one obliges the
supplier to record the messages at the time of a disconnection, and to send them at the time of the new
connection of the consumer.
1.3.3.4.3. Which mode to choose?
A common problem for the architects is of knowing which model to use. Indeed, after some reflections, it
proves that it is possible to make the same thing whatever the model used. However, each of the two models has
interesting characteristics.
JMS provides an access on these two types of models bus to its development, certain companies used the pointtopoint model and others used the model of subscription.
In the majority of the cases, the selected model depends on the use which one wishes to make. The pointtopoint
model will be preferred when it be wished that only one milked recipient the message and to be sure that it is
treated. Conversely, the model of subscription is less restrictive and is used more particularly for the flow of
information which can be used by any customer.

1.3.4. What is an Entity Bean?

13
http://www.supinfo.com

Entity Beans were created to simplify the management of the data on the level of an application, but also to
facilitate the safeguard in data base. More concretely, these Entity Beans enable you to deal with the persistence
of the data of your application in one or more data sources, while keeping the relations between those. These
components thus establish the relation between your application and your data bases. Contrary to the Beans
Session, the data of Entity Bean are preserved, even after the stop of the application.
The application data are typically: users, invoices, products, addresses... In the Java world, and more generally
in the world object, it is common to use classes for each type of objects used. One often speaks about trade
object or entity (English Entity) to represent the characteristics of these objects.

The connection between the data and the application by an object is called the mapping(to connect). The figure
above presents the mapping between the table User and User classifies it. One speaks about Mapping
Object/Relational when one connects, in this manner, a relational database with an Object application.

Warning
The use of Entity Beans makes it possible to represent an entity of the application and not functionality.
For example, User would be Entity Bean, but User Subscription would be a Bean Session; a user being
dedicated to remain persistent, whereas the inscription of the user is a service.
Contrary to the Beans Session, the data of Entity Beans generally have a long lifespan; they are recorded and
stored in systems of persistence (bases data).
The concept is older in EJB, but it starts to appear in the applications Java SE, with the appearance of container
lighter.
1.3.4.1. Persistence
While shortening, it is possible to say that the object to be made persistent, via Mapping Objet/ Relational,
corresponds to a table. Each property of this object is related to a field of the table. Each authority of this object
generally represents a recording of the table. However, it is possible that Entity Bean is distributed on several
tables.
Conversely, a table in a data base gathers a whole of fields. These fields represent either of information directly
related to the table, or of the bonds towards other tables. All this information is not therefore the direct
properties of the object in question.
Entity Bean follows the same principle and must all have a single identifier (key primary education). Entity
Bean AccountInfo, for example, can be identified starting from its account number accountId. This single
identifier makes it possible the application to find the data of Entity Bean associated.
Entity Bean User, for example, is characterized by properties such as: " name ", " first name ", " email ", "
telephone "... These properties are called: persistent fields. These properties are ampped (dependent) with the
fields of the associated table. During the execution of the program, container EJB automatically synchronizes
the state of these properties with the data base.
Like a table, Entity Bean has relational fields. However, a great difference exists. A relational field is
represented, in Entity Bean, by a property whose type is another Entity Bean (fig. 4.2). One speaks about
aggregation, in programming object. With the opposite, a table is related to another table by a foreign key (fig.
4.3).

14
http://www.supinfo.com

1.3.4.2. Instance creation


The creation of authority of an entity is done simply by the simple instantiation of the class by the operator new.
However the persistence of the object created is carried out with API EntityManager. We will see that in detail
more below.
1.3.4.3. Relations
There are 4 possible relations between Entity Beans:

One To One (one by one):


If a user can have one and single account then the relation between the user and his account is of type One
To One

One To Many (with several) and Many To One (several with one):
A user can have several wallets whereas a wallet is held by only one user. The relation between Wallet and
User is of type Many To One and the relation between User and Wallet is of type One To Many.

Many To Many (several with several):


A user has several leisures (hobby) and leisure can be shared with several users. In this case, the relation is of
type Many To Many between user and user.

In the application of example, a user has several wallets of actions. This connection is represented by a relation
One To Many.
1.3.4.4. Heritage
An entity can inherit another, knowing that an entity can as well be an abstract class (see the key word
abstract) that a concrete class (notabstract).
To illustrate this concept, we can see above the diagram of the entities of the application. Indeed, the class
FinancialProduct is abstract. Then, Stock and Jump inherit this class. Indeed, in our software of manager
15
http://www.supinfo.com

of financial products, those can as well be actions sides out of purse (English stock), or obligations (English
jump).
There are 3 strategies of mapping:

a table for a hierarchy of class

a table by concrete class

Strategy consisting in separating the specific fields from a class girl in a table separated compared to the table
containing the data of the table relationship. A junction is then made for instantiate the class girl.
We will study the advantages and the disadvantages of each one of these choices later, but retain for the moment
which that will have of importance only on the level of the performances.
1.3.4.5. Shared access
The entity beans can be divided by multiple customers. As the customers could want to change the same data, it
is important that the entity beans work inside transactions. Typically, the container of EJB provides the
management of transaction. In this case, you specify the attributes of the transaction in the descriptor of
deployment of the bean. You do not need to code the limits of the transaction in the bean; the container defines
the limits for you.
1.3.4.6. Persistence unit
Integral part of the framework Java EE 5, the unit of persistence is it limps black which makes it possible to
return persisting Entity Beans. More than one simple supplier of persistence, this one will make it possible the
developers to optimize their applications according to the management of their Entity Beans.
The unit of persistence is the key element of the management of Entity Beans within an application.
1.3.4.6.1. Database connection
The specification defines a file which gathers the whole of information of persistence. You must name this file:
persistence.xml and to place this file in repertory METAINF, with the root of the project.
This file will be read by container EJB at the time of the deployment of the application. The container then
creates an authority of the supplier of persistence with the required parameters.

Warning
You must name correctly the file persistence.xml. If the name does not correspond, the container will
not associate any context of persistence in the application.
A unit of persistence (Persistence Links) is characterized by the following points:

A whole of Entity Beans

A supplier of persistence, because various manufacturers propose their implementation of the engine of
persistence. For JBoss it acts of Hibernate, and Oracle proposes TopLink.

A data source, like Oracle, PostGreSQL, MySQL, SQL Server... or Derby (a base of data functional, very
light, and written as Java).
1.3.4.7. Persistence Manager

16
http://www.supinfo.com

It acts of a device managing persistence between the data and the unit of persistence.
Entity Manager being an interface, the class of implementation is different according to the supplier used
(defined in the file persistence.xml with the beacon < provider >).
By defect, it is the container which will instantiate EntityManager and which will manage its cycle of life.
1.3.4.8. When to use Entity Beans?
Entity Beans are carried out in the container EJB, which brings to the developers of many services.
The principal service is, of course, the management of the persistence which manages the whole of the access to
the data in the memory or the data sources. The use of this service, and thus of Entity Beans, gets multiple
comparative advantages with the direct access to the data base. This solution brings a simple mechanism for the
access and the modification of the data. Indeed, it is easier, to modify the first name of a user within your
application, to call the method User.setFirstName() to carry out a rough request SQL. Moreover, Entity Beans
being standardized, your code is clear and more easily reusable (the definition of a user is found, for example, in
the majority of the applications).
Entity Bean being an EJB, it inherits the services such as the management of the transactions, of safety... as well
as many development tools optimized for their creation.

1.3.5. The client


The third customer is represented by the applications connecting itself to EJB. These applications are generally
written as Java; however, it is also possible to be connected to a EJB with a customer written in another
language via an access by Service Web (fig. 1.10).
The Java customers generally use JNDI and RMI to connect and call the methods of EJB. So they can as well be
fenestrated graphic applications (called rich customers), other EJB, applications internal, and, obviously, light
customers (Web navigator). It is also possible to make communicate the external systems with a transport interapplication, like JMS.

The client is the public which listens to the concert. The client made the request to return in the room and paid
his ticket with case (RMI), by a retailer (HTTP, Services Web...) or by small advertisements (JMS).
EJB being components server, a customer must obligatorily be set up to be able to communicate with those.
These customers can take several forms:

An application with or without graphic interface

An applet
17
http://www.supinfo.com

A servlet in a Web application

A EJB

Note
You can also call a EJB in a page JSP. Nevertheless, this technique is misadvised because it does not
respect the good principles of the pattern MVC (Model Seen Controller). This model requires that the
access to the Model (service) be done since the Controller (a servlet for example) and not starting from
Sight (JSP).
Knowing that, EJB components are divided by directories. Then the customer locates them via the API JNDI
and their name JNDI. The deployed components are recorded in the directory of the server. Only JNDI pilot
(called service provider) changes one implementation to another.
The calls of distant methods are done by RMI (Remote Method Invocation) whereas the calls of local methods
are done directly in the JVM of the server.

The customer recovers a reference (implementing the interface trade) EJB which it wishes to use. This one can
then call the methods of the object recovered without worrying about the constraints of communication. Indeed,
the call of a method is automatically transmitted to the authority of EJB in the container (generally by a system
of proxy). This authority treats the method and turns over the result to the customer. The creation of the proxy is
with the load of the container and remains completely transparent for the customer.

1.4. Theory
In this part,we are going to study the various components that we must provide for a EJB. We will describe in a
generic way all the rules to be respected. We will observe these rules in the next chapter.

1.4.1. The various steps in creation of a Bean Session


1.4.1.1. Interfaces
A client can reach a Bean Session only through the methods defined in the interfaces of the bean. These
interfaces define the view that the client has on the bean. Neither the Message Driven Beans, nor Entity Beans
need interface.
1.4.1.1.1. Distant clients
A distant client of a Bean Session refers following:

18
http://www.supinfo.com

It can work on a different machine and a different Java Virtual Machine (JVM) from the entreprise bean
which it reach

It can be a web component, an J2EE client application, or an other EJB


1.4.1.1.2. Local clients
A local client has the following characteristics:

It must be executed on the same JVM as the EJB which it reaches.

It can be a Web component or another EJB

They must be deployed together, in the same EAR (equivalent of the JAR for the entreprise applications)
1.4.1.1.3. Client of the WebService type
The Services Web are spread more and more on Internet, because they allow to use any service independently of
the platform or the language.
It is possible to specify the visibility of your EJB with the webservice type so that it can be used as a Service
Web. However, this choice is restricted with the EJB of the type Stateless Session Bean.
1.4.1.1.4. To choose between a distant and local access
The main difference between these two types is undoubtedly the local access or the remote access. If the client
application is executed in the same virtual machine then the local view will be more adapted. The choice should
not be generic, but must for the needs of the application. It is however possible to support the local accesses
while placing an intermediary (the container Web) between the EJB and the distant customer.

Note
In Local mode, the parameters are passed by reference, and in Remote mode, they are passed by value
The webservice view is to be used when the client is not written in Java or when you wish to publish your
service most open possible. Typically, if you wish to give the possibility to your purchasers of consulting your
catalogue of products in any manner, it can be judicious to give them the access this Service Web.
To take again our comparison with an orchestra, the local view would be the spectator in the room and the
distant view, would be an spectator listening on his radio the repeat broadcast placed at the disposal by the
orchestra. The webservice view would be an external chain TV, downloading the recording in the complete
concert, placed at the disposal by the orchestra (Business to Business).
1.4.1.2. Bean Class (implementation)
The bean class of an EJB is the class of execution of the Bean Session. Indeed, it is in this class that you must
program logic trade. The whole of the methods declared in the interfaces (distant/local) will have to be
implemented in this class.
1.4.1.3. Annotations
The annotations are marks in the Java code, which make it possible to configure the application. In the case
of Stateless Bean Sessions, we will place @Stateless on the level of the class of implementation. For Stateful
Bean Session, it is about @Stateful. We will study them in detail when we write our own EJB.
1.4.1.4. Descriptors of deployment

19
http://www.supinfo.com

Well find, in the specification, the files:

application.xml

being used to declare the whole of the modules integrated in a file .ear. You must specify your archive of
persistence in your file application.xml with the following lines:
[CODE:xml]<application xmlns="http://java.sun.com/xml/ns/j2ee" version="1.4"
xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xsi:schemaLocation="http://java.sun.com /xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/application_1_4.xsd">
<displayname>StockManager</displayname>
<description>Demo application</description>
<module>
<ejb>StockManagerEJB.jar</ejb>
</module>
<module>
<web>
<weburi>StockManagerWAR.war</weburi>
<contextroot>/stockmanager</contextroot>
</web>
</module>
</application>

ejb-jar.xml

configure the EJB in a module of a .jar file (optional if the descriptors of deployment related to the
applications servers are specific and depend only of them)

Sun Application Server uses the files sunapplication.xml (ear), sunejb.xml (jar), sunweb.xml (war).

JBoss uses the files jbossapplication.xml (ear), jboss.xml and jbosscmpjdbc.xml (jar), jbossweb.xml (war).
These files make it possible to use advanced functionalities of the server of applications which are not integrated
into the specifications.

Warning
The use of nonstandard functionalities (except specification) involves problems of portability of a
server of applications towards another
1.4.1.5. Assemblage (ou Packaging)
To deliver an application Java EE 5 you must create an enterprive archival file (EAR). It is a standard archival
file with the extension .ear which gathers a lots of modules EJB, Web, Application client... like showed the
following diagram (2.5).

20
http://www.supinfo.com

Each archival file (ear, war, jar or rar) contains a descriptor of deployment organized and structured on model
XML. This one makes it possible to define the parameters of deployment of an application (ear) or a module.
1.4.1.6. Deployment
The step of deployment for the developer is generally very simple. It is enough to place the packaged file in a
special repertory of the server of application or to use the administration of this one.
JBoss requires simply that the file is put in the folder deploy of the current configuration ($ {jboss.home}
/server/ {configuration} /deploy
Glassfish allows the deployment by the interface of administration Web or the administration command line or
by a folder autodeploy.
The task is however more difficult for the server of application. This one must read the contents of the archive,
scan the classes (in order to detect the annotated components), mapper Entity Bean at the database, to lay down
the policy of security (if it is declared), generate the classes (proxy,etc.) according to specificities of the
supplier.
We will more develop the subject of the servers of application in the final chapter
1.4.1.7. Client
Let us start by remember that the EJB are distributed objects. They thus are in a system of naming and relation
client/server. The client must carry out various steps:

To parameterize the environment client.

Connection to the server of naming of the server of application (JNDI)

To recover, with the URL, the stub one corresponding to the class Home of EJB (JNDI/RMI)

Call distants methods.


We will see in detail the whole of APIs to be used for each one of these stages.
1.4.1.8. Conventions of nomenclature
The enterprise beans are composed of multiple elements, so it is useful to follow a convention of nomenclature
for your applications. The following table summarizes conventions (the example is taken on a bean representing
an Account Account).

Table 1.2. Convention of nomenclature of Enterprise Beans


Element

Syntax

Exemple

Nom de l'Enterprise Bean

<name>Bean

AccountBean

EJB JAR

<name>JAR

AccountJAR

Classe de l'Enterprise Bean

<name>Bean

AccountBean

Interface

<name>

Account

Abstract shema

<name>

Account

1.4.2. Specification of a Bean Session


The elements to be set up for a Bean Session are:

21
http://www.supinfo.com

The class Bean

The interface business


1.4.2.1. The class Bean
We use the annotations @Remote or @Local to define respectively if the Bean Session provides the methods to
distant or local clients. It is the same for the types of Beans Session, with the annotations @Stateless or
@Stateful.
[CODE:java]@Stateful
@Remote({ RichClientService.class })
public class RichClientServiceBean implements RichClientService {
}

In this example, the class is annotated with @Stateful in order to declare it as Stateful Session Bean. The
annotation @Remote makes it possible to specify the distant interfaces usable by clients.
1.4.2.2. Cycle of life
1.4.2.2.1. Stateless
Since a stateless session bean is never passivated, its cycle of life has only two states: does not exist and
ready for the call of methods trades:

The Beans Session support the following callback interceptors:

@PostConstruct

The method on which this annotation is put is called when all the dependences of injection carried out by the
container and before the first call of the method trade.

@PreDestroy

The method on which this annotation is put is called at the time when the instance of Bean is destroyed
(during the suppression of Bean or with the stop of the application).
1.4.2.2.2. Stateful
The diagram below illustrates the differents steps for a Bean Session of the Stateful type during its life.
The session bean support the following callback event:

22
http://www.supinfo.com

@PrePassivate (Stateful only)

Allows to specify a method which will be called by container EJB when Bean was inactive and it was
considered to pass this one in a serialized state. This method must be sure that the resources maintained in
instance are released or serializables. We speaks about passivation. The interest of this principle is to
release the memory employed by unutilised Stateful for the moment. The container then can serialize the
instance on an external medium (hard disk...).

@PostActivate (Stateful only)

Its the reverses of @PrePassivate. This annotation allow to specify the method which will be called by the
container when a Bean must be reactivated from its state of passivation. Bean will have to find an operational
state by recovering the resources released during passivation. We speaks about activation.

The passivated state is reserved for Stateful Session Beans because they are the only ones to share a state with
the customer. The life cycle of this component starts with the first call of a business method. The container then
creates an instance with the Class.newInstance method (). It injects the dependences and calls the methods
annotated with @PostConstruct. The great difference with the Stateless type is that Stateful integrates the
concept of passivation. The implementation of this concept is specific to the container and can vary from one
client to another. In all the cases, the container calls the methods annotated with @PrePassivate and
@PostActivate at the time of the passivation and the activation of the component.
The instance is removed when the customer calls a method annotated with @Remove or when the time assigned
for the session is exceeded (timeout).
1.4.2.3. Exemple
Here a very simple example of SessionBean (stateless type). The interface should of course be defined that our
bean will implement. Here we define simply the Remote interface which contains only one method: getHello ().
Moreover let us annotate it with the annotation @Remote in order to declare it like distant interface.
Here the code of the distant interface (Remote):
[CODE:java]import javax.ejb.Remote;
@Remote
public interface RemoteHello {
public String getHello();
}

The bean class implements the preceding interface and is annotated by @Stateless in order to declared it as
Session Bean Stateless.
Here the code of this class:
[CODE:java]import javax.ejb.Stateless;

23
http://www.supinfo.com

import com.society.testejb3.interfaces.RemoteHello;
@Stateless
public class HelloBean implements RemoteHello {
public String getHello() {
return "Hello world";
}
}

1.4.2.4. Dependence between Beans Session


As we see previously with Entity Manager, you can specify to the container that your EJB is on another. The
container will be given the responsability automatically to inject the required instance. Its why, you just have to
annotate the property with @EJB. Here, an example using this annotation:
[CODE:java]@Stateful
@Remote( { RichClientService.class })
public class RichClientServiceBean implements RichClientService {
@EJB
private CommonService commonService;
}

The RichClientServiceBean class defines a variable of instance commonService whose type is CommonService (the
business interface related to the EJB). With the annotation @EJB positioned on this property, the container
automatically injects an instance of the EJB (CommonServiceBean) when the instanciation of the EJB
RichClientServiceBean. I.e. it makes, in your place, JNDI research and the automatic initialization of the
dependence towards this EJB.
For certain more complex cases, the annotation @EJB admits attributes which allow to specify the localization
of the EJB.

beanName

Specify the name of the EJB (specified by the attribute name of the annotations @Stateless, @Stateful or in
the descriptor of deployment with the markup <ejbname>).

beanInterface

Specify the business interface that we wish to use. This attribute is mainly indicated when you use an
interface related of the business interface implemented by Bean. The default interface is used by the variable
which is subject to the injection

mappedBy

Specify JNDI name to be used to seek the instance of Bean.


EJB3 Specification wishes to hide these JNDI calls which often diverted the developers. However, the injection
has its limits and is available only within one container.

Warning
the annotation @EJB in a rich customer application (console or graph) is available only when this one
is launched in the Application Container Client (AAC). The installation of this type of application is
explained hereafter.

1.4.3. The client view


The client of a EJB does not work directly with EJB system. Moreover, the client reaches with interfaces to
beans and their business logic. These interfaces gather the API JNDI (Java Naming Directory Interface) and an

24
http://www.supinfo.com

API EJB Client. While JNDI is used to locate and reach the EJB in a transparent way, API EJB Client is a whole
of interfaces and classes which the developer uses to work with the beans.
We will see in this chapter several small examples of code allowing to locate/reach/work with the beans. You
will find a complete code in the chapter: EJB with practice. JNDI is a standard in java. It allow to standardize
connection to a service of directory, like does it JDBC for databases. There are many suppliers of directory, each
one of them must provide its own driver for its type of directory (LDAP, File system, EJB...).
1.4.3.1. Localization of bean with JNDI
Here an example allowing a client to recover a reference towards the Session Bean RichClientServiceBean.
[CODE:java]try {
Context ctx = new InitialContext();
ctx.put("java.naming.factory.initial","org.jnp.interfaces.NamingContextFactory");
ctx.put("java.naming.factory.url.pkgs","org.jboss.naming:org.jnp.interfaces");
ctx.put("java.naming.provider.url","127.0.0.1:1099");
// le nom JNDI par dfaut est
// "Nom du fichier EAR/Nom de la classe du bean/type accs : local/remote"
richClientService = (RichClientService)
ctx.lookup("StockManager/RichClientServiceBean/remote");
} catch (NamingException e) {
// gestion des erreurs
}

The object Context allow to initialize the parameters of connection to the directory to communicate with its.
Among the parameters of the example, we finds in particular the URL of the register, here with the 127.0.0.1
address. Thus when the server of application is not on the same machine that the client, this adresse IP should be
modified. Moreover, the first two parameters are specific to JBoss and the values correspond to objects located
in the bookshops client of this server.
The principle is the same for a client in a Web application, an application console or another EJB.

1.4.4. Use of JMS and the Message Driven Bean


1.4.4.1. ConnectionFactory and Destination
To work with JMS, the first stage is to connect itself to supplier JMS. It is necessary to recover a
ConnectionFactory object with JNDI which makes connection possible with the supplier. This object can be
compared to a DataSource (in JDBC). Indeed, in the same way that DataSource provides a connection JDBC,
ConnectionFactory provides a connection JMS to the service of routing of message.
Here an example detailing the recovery of ConnectionFactory and a Destination:
[CODE:java]Context jndiContext = new InitialContext();
ConnectionFactory connectionFactory = (ConnectionFactory) jndiContext.lookup("ConnectionFactory");
Destination destination = (Destination) jndiContext.lookup("queue/MyQueue");

The other element to recover is the destination. It represents the place on which the application wishes to work
(sending or reception of message). We will see in the following part that there are two types of destinations:
topics and tails.
1.4.4.2. Connection and Session
The ConnectionFactory object makes it possible to create a connection with supplier JMS. Once connection
created, it is used to create a session.
[CODE:java]Connection cnx = connectionFactory.createConnection();
Session session = cnx.createSession(true, 0);

The session is used to group the operations of sendings and receptions of messages. In the majority of the cases,
a single session is sufficient. The creation of several sessions is useful only in the case of multithread
application which produce and receive messages at the same time. Indeed, the Session object is threadsafe, i.e.
its methods do not authorize the concurent access. Generally, the thread which creates the Session object uses
the producer and the consumer of this session.
25
http://www.supinfo.com

The method createSession() need two parameters:


[CODE:java]createSession (boolean transacted, int acknowledge)

However, the specification indicates that the value of these arguments is ignored within container EJB. Indeed,
this one manages the transactions and the acknowledgements of delivery according to the parameters of
deployment.

Warning
Certain suppliers do not adhere completely to the specification and are not unaware of the parameters.
The good practices of development encourage to close connections once the work is completed.
[CODE:java]Connection cnx = connectionFactory.createConnection();
// [...]
cnx.close();

1.4.4.3. MessageProducer and MessageConsumer


The last step is the sending and the reception of messages. It is necessary to create objects of the type
MessageProducer and MessageConsumer respectively to send and receive messages.
[CODE:java]MessageProducer producer = session.createProducer(destination);
MessageConsumer consumer = session.createConsumer(destination);

Each method takes in parameter the destination on which the object is connected.
1.4.4.4. Type of Message
In JMS, a message is a Java object made up of a heading and a body. The heading is composed of information
of destination, expiry, priority... The body of the message contains data being able to be various types:

Text with TextMessage.

Serialized object with ObjectMessage.

Map with MapMessage.


Each one of these types of messages inherits javax.jms.Message.
Let us take the case of MapMessage, where a message asks for the purchase of 250 actions of the company
JavaCorp. This information would be transmitted in an object of the MapMessage type:
[CODE:java]MapMessage mapMsg = session.createMapMessage() ;
mapMsg.setInt("action", StockAction.BUY_STOCK) ;
mapMsg.setString("company","JavaCorp") ;
mapMsg.setInt("number",250);
producer.send(mapMsg);

Another solution consists in sending a serializable object directly :


[CODE:java]StockAction stock = new StockAction();
stock.setAction(StockAction.BUY_STOCK);
stock.setCompany("JavaCorp");
stock.setNumber(250);
ObjectMessage objectMsg = session.createObjectMessage();
objectMsg.setObject(stock);
queueSender.send(objectMsg);

Two other types of messages are available to treat array of bytes and the primitive types, which are
26
http://www.supinfo.com

BytesMessage and StreamMessage. Those use data flows.

1.4.4.5. Clients Applications


There are various interfaces according to the model of message used. However an interface common to both
models exists and provides a whole of sufficient methods in the majority of the cases!
1.4.4.5.1. Producing client
Here an example of client application which is used to produce and to send messages.
[CODE:java]public class JMSSender {
public void sendMessage(String text) throws Exception {
Context ctx = new InitialContext();
ConnectionFactory connectionFactory = (ConnectionFactory) ctx.lookup("ConnectionFactory");
Destination destination = (Destination) ctx.lookup("queue/StockValue");
Connection cnx = connectionFactory.createConnection();
Session session = cnx.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageProducer producer = session.createProducer(destination);
TextMessage message = session.createTextMessage();
producer.send(message);
cnx.close();
}
}

We find the whole of the components quoted previously ( ConnectionFactory, Destination, Session ...).
The properties for the creation of Context JNDI are dependent on supplier JMS used. Here values used for
GlassFish:
[CODE:java]Hashtable hashtable = new Hashtable();
hashtable.put("java.naming.factory.initial", "com.sun.enterprise.naming.SerialInitContextFactory");
hashtable.put("java.naming.factory.url.pkgs", "com.sun.enterprise.naming");
hashtable.put("java.naming.provider.url", "iiop://localhost:1050/");
Context jndiContext = new InitialContext(hashtable);

Here those for JBoss:


[CODE:java]Hashtable hashtable = new Hashtable();
hashtable.put("java.naming.factory.initial", "org.jnp.interfaces.NamingContextFactory");
hashtable.put("java.naming.factory.url.pkgs", "com.sun.enterprise.naming");
hashtable.put("java.naming.provider.url", "localhost:1099");
Context jndiContext = new InitialContext(hashtable);

Note
These data are as an indication and can change according to the evolution of the various versions of
these server of application.
Here a summary table of the specific interfaces which can be used for a message of the pointto point type:

Table 1.3. Correspondence between the generic interfaces and those specific to the
pointtopoint transport
Generic

Specific point to point

ConnectionFactory

QueueConnectionFactory

Destination

Queue

Session

QueueSession

MessageProducer

QueueSender

Here a summary table of the specific interfaces which can be used for a transport of the type subscription:

Table 1.4. Correspondence between the generic interfaces and those specific to the
transport by subscription
27
http://www.supinfo.com

Generic

Specific subscription

ConnectionFactory

TopicConnectionFactory

Connection

TopicConnection

Destination

Topic

Session

TopicSession

MessageProducer

TopicPublisher

1.4.4.5.2. Consuming client


The code of the consumer is very similar to the preceding code. Indeed, the only things which differ are the
recovery of MessageConsumer and the sending of the message.
[CODE:java]public class JMSReceiver {
public void receiveMessage() throws Exception {
Context ctx = new InitialContext();
ConnectionFactory connectionFactory = (ConnectionFactory) ctx.lookup("ConnectionFactory");
Destination destination = (Destination) ctx.lookup("queue/StockValue");
Connection cnx = connectionFactory.createConnection();
Session session = cnx.createSession(false, Session.AUTO_ACKNOWLEDGE);
MessageConsumer consumer = session.createConsumer(destination);
consumer.setMessageListener(new MessageListener() {
public void onMessage(Message message) {
System.out.println(message);
}
});
cnx.start();
}
}

In this example, we use the concept of listener avoiding any blocking of the application when the reception of a
message. For that, we must implement the MessageListener interface. The method onMessage (Message
message) is then called automatically at the time of the reception of a message

Warning
Do not forget to start connection with the method start() if not no message will be received.
By the same way as the producer, the consumer can use more specific interfaces for each model of transport.
Here a summary table of the specific interfaces which can be used for a transport of the pointto point type:

Table 1.5. Correspondence between the generic interfaces and those specific to the
pointtopoint transport
Generic

Specific point to point

MessageConsumer

QueueReceiver

Here a summary table of the specific interfaces which can be used for a standard transport subscription:

Table 1.6. Correspondence between the generic interfaces and those specific to the
transport by subscription
Generic

Specific subscription

MessageConsumer

TopicSuscriber

1.4.5. Writing of a Message Driven Bean (consuming messages)


1.4.5.1. The class of Bean
Now in EJB 3, it is not obligatory any more to implement the MessageDrivenBean interface. Only the
annotation @MessageDriven is necessary to define your class as MDB. But the implementation of

28
http://www.supinfo.com

MessageListener is necessary if the MDB works with JMS.


[CODE:java]@MessageDriven(name = "StockValueListener",
activationConfig = {
@ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Topic"),
@ActivationConfigProperty(propertyName = "destination", propertyValue = "topic/StockValueTopic")}
)
public class StockValueListenerBean implements MessageListener {
@Resource
private MessageDrivenContext ctx;
public void onMessage(Message message) {
// TODO => update stock value procedure
}
}

All is realizable with the annotations.


The annotation @MessageDriven makes it possible to define the name of the MDB within the container (attribute
name). The attribute activationConfig allow to configure the properties of the MDB. In the preceding example, we
define the type of destination destinationType and name JNDI of the destination used (destination). For that, we
use an array of @ActivationConfigProperty specifying the name of the property propertyName and its value
propertyValue.

Warning
The attribute mappedName is not to use because it is not portable between the various server of
applications.
It is possible to recover the context of the MDB with the injection (annotation @Resource). The type of this
object is MessageDrivenContext. We detail his use further.
You can notice that the development of MDB is really simplified. Now ,we will study the various points of
details of these components.
1.4.5.2. MessageDrivenContext
As the Beans Session, the Message Driven Beans also have a context of execution of the
MessageDrivenContext type. It is similar to the SessionContext object explained in the part Session Bean.
Indeed, this interface inherits EJBContext and does not add any method.
1.4.5.3. Tolerance of the disconnection to a topic
The model of transport of the type subscription obliges the client applications to be connected to the subject
(topic) to receive the messages of this one. If a problem of connection occurs, the disconnected client lose the
messages transmitted during their disconnection.
However, as we had specified at the beginning of this chapter, the topic mode makes it possible to use a durable
subscription. The interest is to be able to receive the messages transmitted since the last disconnection.
The use of this kind of subscription must be specified on the level of the properties of the MDB. The property to
be used is subscriptionDurability. The values taken by this one are: Durable or NonDurable. By default, a
subscription is NonDurable.
[CODE:java]@MessageDriven(
activationConfig={
@ActivationConfigProperty(propertyName="subscriptionDurability",propertyValue="Durable")
}
)

Other properties exist and can be used (subscriptionName, clientId...).


When the destination is of Queue type, the principle of durable subscription does not have any sence. By nature
for this kind of destination, the durable factor does not have importance because the messages are

29
http://www.supinfo.com

automatically stored and must be consumed by a single customer.


1.4.5.4. Selector of message
It is possible to specify certain criteria allowing not to receive the whole of the messages from a destination. The
selector of message uses the properties of the message as a criterion in the conditional expressions. These
conditions use Boolean expressions in order to determine the messages to receive. Here an example of use of
these selectors of message.
[CODE:java]@ActivationConfigProperty(propertyName="messageSelector",propertyValue="senderType='StockSender
Corp'")

These selectors are based on the properties of the messages. Those are located in the heading of the message,
therefore depending of the contents, and are assigned by the creator of the message. All the types of message
integrate the methods of reading and writing of properties. Indeed, these methods are described in the interface
javax.jms.Message (superinterface defining a message). The types of properties are based on the Java primitives:
boolean, int, shorts, char...
To define the values of the properties it is necessary to use the methods setXxxProperty(Xxx) where Xxx represent
the types byte, float, String, Object... The methods getXxxProperty() are also proposed to recover the values. In the
following example, we define properties on which we will be able to define criteria of recovery.
[CODE:java]TextMessage message = session.createTextMessage();
message.setText("Les indices boursiers Paris ont gagn 4% aujourdhui") ;
message.setIntProperty("result",4);
message.setStringProperty("place","FR/Paris");
message.setStringProperty("senderType","StockSenderCorp");

Thanks to the properties which we have just defined, we can apply criteria of selection.
[CODE:java]@MessageDriven(activationConfig={
activationConfig= {
@ActivationConfigProperty(
propertyName = "messageSelector",
propertyValue = "place = 'FR/Paris' and result > 0")}
}

The system is based on the same concepts as the selection of the recordings with SQL. You can use operators
AND, OR, <, >... Other functionalities are possible. Let us take the case where we wish to treat in a MDB all the
messages having a relationship with the money markets Parisian, London, and francfortoise.
[CODE:java]place IN ('FR/Paris', 'UK/London', 'GER/Francfort')

We can also think to an alarm system, if the one day result is not located between +10% and 10%, to warn the
investor that this day is not an ordinary one.
[CODE:java]result NOT BETWEEN 10 AND 10

Or treatment of the stock exchange places French or English


[CODE:java]place LIKE 'FR/%' OR place LIKE 'UK/%'

This functionality is useful when we wish to sort and distribute the messages located in the same destination
towards various MDB, in order to apply different treatments to them.
1.4.5.5. Acknowledgement
The disadvantage of the asynchronous treatment of messages is that there is no value of return to sender. It is
difficult for him to know if the message were indeed transmitted (when it wishes to know, of course). There are
various solutions to this problem.
The first consists in using acknowledgements of delivery, transparent mechanism managed by the supplier and
container MDB. It allow the client application to warn to the supplier that the message was received. Without
this acknowledgement of delivery, the message will continue to be sent.
This mechanism is based on the transactions on the level of the MDB. When this one is managed by the

30
http://www.supinfo.com

container, the acknowledgements just after the commit, or not if the transaction fails.
There are two modes of acknowledgement: Autoacknowledge and Dupsok acknowledge. The mode Autoacknowledge defines that the acknowledgement must be sent as soon as the message was transferred to the
MDB.
[CODE:java]@MessageDriven(
name="MyQueue",
mappedName = "queue/MyQueue",
activationConfig={
@ActivationConfigProperty(propertyName="acknowledgeMode",propertyValue="Autoacknowledge")
}
)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class MyTopicListener implements MessageListener {
// ...
}

For Dupsokacknowledge, the acknowledgement is pushed back at one unspecified moment and the container
chooses then the moment when it has few tasks to treat to send it. That permit to save the resources. One can
however disadvise this last value because the supplier could believe that the message was not treated and would
decide to transmit it again (what could involve dysfunctions). Moreover, the cost of sending an
acknowledgement of delivery is negligible that it is in capacity of calculation or load network.
[CODE:java]@MessageDriven(
name="MyQueue",
mappedName = "queue/MyQueue",
activationConfig={
@ActivationConfigProperty(propertyName="acknowledgeMode",propertyValue="Dupsokacknowledge")
}
)
@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public class MyTopicListener implements MessageListener {
// ...
}

The second solution consists in specifying the JMSReplyTo value in the parameters of heading of the message.
That makes it possible to the recipient to send an answer towards the parameterized destination. As regards
shipper, we define the destination of answer in the following way:
[CODE:java]Destination replyDestination = context.lookup("queue/ReplyQueue");
message.setJMSReplyTo(replyDestination);

The MDB receiving the message can then recover this property and send in its turn a message.
[CODE:java]Destination replyDestination = message.getReplyTo();

This method differs from preceding because it allows a real information feedback concerning the treatment of
the message. This solution is typically used in our example of forwardings. The message of return alerts the
system when the object is prepared and dispatched. That could not have been implemented with the first
solution. This solution is also interesting to go up reports/ratios of errors in the business process.
1.4.5.6. MDB and JMS client
We directed our presentation MDB and JMS mainly towards the consumption of messages more than on the
production of these messages. There exists however many evolutions facilitating the development of the sending
of these messages.
Let us point out the various steps for sends of a message JMS:

Recovery of a ConnectionFactory object

Recovery of the destination

31
http://www.supinfo.com

Opening of a connection

Creation of a session

Creation of a MessageProducer

Creation of a Message

Sending of the message

Disconnection.
[CODE:java]public class StockAlertListener {
@Resource (mappedName = "ConnectionFactoryName")
private ConnectionFactory cnxFactory;
@Resource (mappedName = "queue/StockAlertQueue")
private Queue stockAlertQueue;
public void sendAlertMessage(String textAlert) {
Connection cnx = cnxFactory.createConnection();
Session session = cnx.createSession(true, 0);
MessageProducer producer = session.createProducer(stockAlertQueue);
TextMessage message = session.createTextMessage();
message.setText(textAlert);
producer.send(message);
cnx.close();
}
}

The first two steps of recovery are automated with the principle of injection. For that, we used the annotation
@Resource which defines name JNDI of ConnectionFactory and the Destination (of Queue type, here).
The code of the method sendAlertMessage (String textAlert) do not changes a lot compared to the implementation
code client presented before.

Note
The examples presented in this part can completely be implemented within a Bean Session exactly in
the same way.
1.4.5.7. Life cycle
Just like the Session Beans, a Message Driven Bean has a cycle of life managed by the container. This type of
component has only two states: Does not exist and ready Method.

32
http://www.supinfo.com

A MDB is in the state does not exist when there is not any instance in memory of this one (it was not
instanciate yet). A MDB is in the state Method ready when the instance is ready to be used. Once the
application started, the container creates a whole of instance of MDB of which the state is ready Method.
The following steps describe the changes of state which a MDB can undergo:

The instance is created when the container calls the method newInstance() in the class of the component
(generally with the starting of the application). Then, the container injects all the dependences of the object.
These dependences gather the injections annotated with @Resource, @EJB... then the container calls the
methods annotated with @PostConstruct. The instance is now ready to treat the messages delivered with the
listened destination: state ready Method.

When the container does not need more the instance, it calls the methods annotated with @PreDestroy. That
generally occurs when the reserve of instances becomes disproportionate compared to the needs or that the
application stops.
The interest of the method declared with @PostConstruct is to open a connection towards a service, like the
access to a directory of company or more simply to a file. The second method, @PreDestroy, are used to release
the resources used.
[CODE:java]private FileWriter fw = null;
@PostConstruct
private void connectToFile() {
try {
fw = new FileWriter(new File("save_topic.txt")) ;
} catch(Exception e) { ... }
}
@PreDestroy
private void unconnectToFile() {
try {
fw.close();
} catch(Exception e) { ... }
}
public void onMessage(Message message){
try{
//...
fw.flush();
} catch(IOException ex) {
ex.printStackTrace();
}
}

Notice that we forced the writing in the file at the end of the method onMessage() with FileWriter.flush(). The
interest is to be sure that the file is written. Indeed, for certain reasons, the methods of recall can not be called
33
http://www.supinfo.com

and the data remained in memory can be lost.

1.4.6. Specification of Entity Bean


1.4.6.1. Class of Bean
The Entity Bean class is the first element to be defined in EJB 3. Like known as previously, Entity Beans are
POJO (Plain Old Java Objects ). So the creation of an Entity Bean User is summarized with the creation of an
User class, such as we would do it in an application Java SE. The persistent state of the entity is represented by
the variables of instance of the class which correspond to the properties of the POJO. These variables can be
private, be protected or not specified. The client cannot reach directly the variables and must use the getter and
setter or other methods trades of the class.
This class must, however, comply with certain rules:

This class can be abstract or concrete.

The class can as well inherit a class entity as a class not entity, and conversely.

The methods, the properties of the class and the class itself should not be final

If an instance of the entity have the possibility of being sent to a distant client, then the class must implement
java.io.Serializable. Indeed, RMI uses the (un)serialisation to pass the arguments between the client
application and the client.

The class must have a constructor without argument which can be public or protected. Nevertheless, the class
can have overrided manufacturers if the preceding condition is observed.

Note
The goal of the default constructor (without argument) is to simplify the instanciation of the class by
the container. The dynamic management of any constructor is a heavy task for this one without to be
useful. The solution was to define a constructor common to all Entity Bean: the default constructor.
EJB 3 Entity Beans support the heritage, associations and the polymorphic requests. These various concepts will
be explained throughout this chapter.
[CODE:java]@Entity
public class User {
//...
}

It is with the annotation @Entity that the container will be able to know which classes must be consider as Entity
Bean. This annotation is on the class and allow to define, the name of the entity with the attribute name.
The name used must be unique in an application. The default value used is the name of the class (User in the
preceding example). This name is used to represent the entity in the requests EJBQL, which we will see later; it
is the abstract diagram of Entity Bean.
[CODE:java]@Entity(name = "MyUser")
public class User {
//...
}

Entity Bean is related to a table in database. This connection is called the mapping. By default, Entity Bean User
is mapped on the table User. If for certain reasons, you want to map on another table, you will have to use the
annotation @Table. This annotation has various attributes:

34
http://www.supinfo.com

name (required): defines the name of the table to use for the mapping.

catalog (optional): define the catalogue used.

diagram (optional): define the diagram used.

uniqueConstraints (optional): defines the constraints which will be placed on the table. This attribute is used

when the container generates the tables with the deployment and of anything the execution even entity does
not affect.
[CODE:java]@Entity
@Table(name = "XUser")
public class User {
//...
}

Note
The name table User is a reserved name in certain databases like PostGreSql, therefore we named it
in the example above XUser.
1.4.6.1.1. Persistent fields
A persistent field represents a property of Entity Bean. For an user entity, it will be for example: the name, the
first name, the address, the date of birth, the sex...
Any field (variable of instance) not static and not transient, of Entity Bean, is automatically considered as
persistent by the container.
A set of standard annotations is defined in EJB 3 specifications. We can consider two types of annotation related
to Mapping Objet/Relationnel :

annotations related to the properties

annotations related to the columns


These two types of annotations, which will be described in a more detailed way in the following parts, can be
placed in two ways:

Directly on a field

On the getter and setter (more precisely on the getter)


1.4.6.1.2. Default Mapping
When you will create your bean, you will need to map the whole of your fields. However it is possible to use the
default mapping. This mapping will be used when you do not use an annotation for a field (that it is persistent or
relational), and that corresponds to the annotation @Basic. So it is to the manager of persistence selecting the
suitable type of variable.
The policy of API Persistence is to consider any property as a persistent field. That means that it is not
necessary to annotate the properties to indicate them persistent. The container considers by default that the
property is annotated with @Basic with the default values of the following attributes:

35
http://www.supinfo.com

fetch (FetchType.EAGER default) : determines whether the contents of the property must be in charge with the
request 1 (FetchType.LAZY) or at the time of the loading of the entity ( FetchType.EAGER).

optional (true default) : determines whether the property accepts or not the value " null". This attribute does not
function for the primitive types (which cannot be null).

Other annotations allow to specify the parameter setting of the columns (in the relational table) related to the
persistent properties. With those, it is then possible to specify type SQL, the length of the field, and many other
properties to be used for a persistent property.
The annotation @Column will be necessary to use to specify these parameter settings SQL. This one ondefine
default values declared by EJB 3 specification. This annotation can be used jointly with the preceding ones.
Here a description of the attributes, all optional, annotation @Column:

name: specify the name of the dependent column. The name of the property is used by default.

unique: specify if the property is a unique key or not (the value is unique in the table).

nullable: specify if the column accepts null values or not.

insertable: specify if the value must be included during the execution of request SQL INSERT. The default

value is true.

updatable: specify if the value must be updated during the execution of request SQL UPDATE. The default

value is true.
columnDefinition: specify the piece of code SQL for the definition of the column in the database. It is with

this attribute that we can specify the SQL type of the column.

table: specify the table used to contain the column. The default value is the principal table of the entity. This

attribute is used when Entity Bean is maped with several tables.

length: specify the length that the data base must associate a field text. The length by defect is 255.

scale: specify the fixed number of figures after the decimal separator (in general the point). This attribute is

usable only for the decimal properties (float, double...). The default number of decimal is defined by the
database.
[CODE:java]@Column(updatable = true, name = "price", nullable = false, precision=5, scale=2)
public float getPrice() { return price; }

The many default settings of API Persistence offers an advantage to the developer. This one can quickly test its
entities. However, it should not remain there, but use the possibilities exposed about it here to optimize the
mapping between its entities and the database.
1.4.6.1.3. Primary Key
Entity Bean must have a field whose value is unique, known as primary key. This field allow to differentiate
each instance from the entity of the others. This primary key must be defined only once in all the hierarchy of
36
http://www.supinfo.com

Entity Bean.
There are two types of identifier: simple and composite. We explain, in this part the first case the second is more
rarely used.
1.4.6.1.3.1. Simple Identifier
We speaks about simple identifier when this one is composed by a single field whose type is simple. The
simple types are: primitive types (int, float, char...), a wrapper (For example Integer, Float, Double...), the String
type or Date (java.util.Date or java.sql.Date).

Note
In general, the decimal ones (a number with comma) are not used as a primary key. The entities using
this type for the primary key are likely not portable.
To specify with the container that a field is a primary key, it is necessary to annotate this one with @Id. In our
Entity Bean User, the primary key is assigned with the field id.
[CODE:java]@Entity
public class User implements Serializable {
private int id;
@Id
@GeneratedValue(strategy = GenerationType.AUTO) // optionnel
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}

The last example uses the annotation @GeneratedValue which allow to indicate to the container to use the best
solution for the generation of the primary key. There are four strategies of generation available: AUTO,
IDENTITY, SEQUENCE and TABLE. Those are defined by the enumeration javax.persistence.GenerationType.
IDENTITY type indicates to the supplier persistence assigning the value of the primary key by using the column

identity of the data base. Under MySQL, for example, the autogenerated primary key is marked with
AUTO_INCREMENT.
[CODE:java]@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
public int getId() { /* ... */ }

The SEQUENCE type, as its name indicates it, obliges the supplier of persistence to use a sequence of the
database. This one can be declared on the class or the package with @SequenceGenerator and its attributes:

name (require): a unique name for the sequence which can be referred by one or more classes (according to

the level used for the declaration of the annotation)

sequenceName (optional): defines the name of the sequence object of the database which will be used to

recover the values of the dependent primary keys.

initialValue (optional): the value which must start the sequence.

allocationSize (optional): defines the number used for the incrementing of the sequence when the supplier of

37
http://www.supinfo.com

persistence reaches it.

Warning
The default value for the attribute allocationSize is 50
[CODE:java]@Entity
@SequenceGenerator(
name="SEQ_USER",
sequenceName="SEQ_USER"
)
public class User {
private int id;
@Id
@GeneratedValue(strategy=GenerationType.SEQUENCE, generator="SEQ_USER")
public int getId() { return id; }
}

This type of generation is useful when the database offers a native system of sequence and that it is advised to
use it by the supplier of this one.
The TABLE type indicates to the supplier persistence using an additional table to generate the numerical primary
keys. This case of use is rarest.
[CODE:java]@Entity
@TableGenerator(
name="CONTACT_GEN",
table="GENERATOR_TABLE",
pkColumnName = "key",
valueColumnName = "hi",
pkColumnValue="id",
allocationSize=25
)
public class User {
private int id;
@Id
@GeneratedValue(strategy=GenerationType.TABLE, generator="CONTACT_GEN")
public int getId() { return id; }
}

The annotation @TableGenerator allow to specify the parameters of creation of the additional table of
generation. Here the detail of the attributes of this one:

name: a name for this definition of additional table

table: the name of the table in the database

pkColumnName: specify the name of the column which identifies the primary key for which the key is

generated.

valueColumnName: specify the name of the column which contains the meter of the primary key.

allocationSize: the number of incrementings carried out when the supplier requests from the table a new value.

That allow to the supplier to use a system of cache in order not to require a new value of each request for new
a id.
The AUTO type indicates to the supplier persistence using the best strategy (between IDENTITY, TABLE,
38
http://www.supinfo.com

SEQUENCE) according to the data base used. The generator AUTO is the type preferred to have a portable

application.
Even if the automatic incrementing of the primary key relieves the developer, it must be used with parsimony.
Indeed, it is preferable to use a field of the entity rather than to add one of them, especially for the primary key.
For example, the entity Account can contain a property accountNumber which wants to be single by banking
logic. This property is then the best candidate for the primary key.
1.4.6.1.4. Simple Exemple
Here an example of simple POJO. It allow to define the structure of table " COUNTRY". It implements
java.io.Serializable in order to be able to be sent directly to a distant client (and thus to pass through a network).
The obligatory annotations are:

@Entity which declares the class as being an entity

@Id which declares the primary key (generate allow to define the type of generation to be used for this key.
GeneratorType.AUTO defines a key incremented car).
The other annotations are not obligatory allow to specify more precisely various parameters:

@Table defines the name of the table to be used

@Basic defines the type of a persistent field (by defect, this type is used)
[CODE:java]@Entity
@Table(name = "COUNTRY")
public class Country implements Serializable {
private int id;
private String name;
public Country() {
}
@Id(generate = GeneratorType.AUTO)
@Basic
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

1.4.6.2. Relations
We saw the definition of persistent property previously. It proves that an entity generally does not work only but
that it is connected to other entities. We speak then about relations between entities.

39
http://www.supinfo.com

To define a relational field within an entity, it is enough to create a property whose type is an entity (cardinality
1) or a whole of entity (cardinality N). A relation is known as oneway if only one part knows the relation. On
the other hand, it is described as bidirectional if the two parts know it.
For the relations where one side, at least, is multivalued ("One to Many", "Many to One", "Many to Many"), the
types of containers available are: java.util.Collection, java.util.Set, java.util.List, and java.util.Map.
They are these relations between entity EJB 3 which we detail in the next parts.
1.4.6.3. One to One
A relation "One to One" is used to bind two indissociable uniques entities. For example, a body has one heart, or
a person has only one indentity card. We will suppose, in our example, which a user User has one AccountInfo
account.
To associate two entities with this type of relation, the annotation @OneToOne should be used. This one takes
again the attributes of @Basic, considering previously, and proposes other optional attributes:

cascade: specify the operations to be carried out in cascade.

mappedBy: specify the field owner of the relation the case of a bidirectional relation.

targetEntity: specify the class of a target entity. This attribute is not used a lot because the annotation uses the

type of the property automatically.


This type of relation can be mapped with 3 manners in the database.
The first solution consists in using the same values for the primary keys of the two entities. It is then necessary
to specify this choice via the annotation @PrimaryKeyJoinColumn (joint by primary key). Here the example of the
oneway relation between User and AccountInfo with this method.
[CODE:java]@Entity
public class AccountInfo {
private int id;
private String cardNumber;
private double amount;
private String accountId;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
// Others getters and setters
}

40
http://www.supinfo.com

[CODE:java]@Entity
public class User {
// ...
@OneToOne
@PrimaryKeyJoinColumn
public AccountInfo getAccountInfo() {
return accountInfo;
}
// ....
}

The second solution consists in using a foreign key on a side of the relation. However, it should be noted that
the column of this key must be marked like single in order to simulating correctly the relation One to One.
The annotation to use is @JoinColumn. It makes it possible to parameterize the column of joint to be used. The
example shows the bidirectional relation.
[CODE:java]@Entity
public class User {
// ...
@OneToOne
@JoinColumn(name="account_id", referencedColumnName="id")
public AccountInfo getAccountInfo() {
return accountInfo;
}
// ...
}

The

annotation @JoinColumn resembles @Column but has an optional additional attribute:


referencedColumnName. This one makes it possible to specify the name of the column referred by the foreign
key of association.
[CODE:java]@Entity
public class AccountInfo {
// ...
private int id;
private User user;
@OneToOne(mappedBy = "accountInfo")
public User getUser() {
return user;
}
// ...
}

The attribute mappedBy declares that the side owner is that holding the property accountInfo. It is thus, here, the
User entity which holds the relation and thus has the capacity to bind a user on an account (the reverse being
impossible).
The last solution consists in using a table of association of the links between the two entities. However, the
multiplicity One to One is respected if and only if one unique constraint is defined on each foreign key. Even
if this case is rarer, it is possible to find it in an existing system which one wishes to make evolve.
[CODE:java]@Entity
public class User {
// ...

41
http://www.supinfo.com

@OneToOne
@JoinTable(name = "UserAccountInfo"
joinColumns = @JoinColumn(name="user_fk", unique=true),
inverseJoinColumns = @JoinColumns(name="accountinfo_fk",
unique=true)
)
public AccountInfo getAccountInfo() {
// ...
}
}
@Entity
public class AccountInfo {
//...
@OneToOne(mappedBy = "accountInfo")
public User getUser() {
// ...
}
}

This technique obliges to write more lines, without to increase the performances. It is however a considerable
case when we use of an existing data source. The annotation @JoinTable allow to configure the table of joint for
relation. Here a description of the attributes of this one:

name: specify the name of the joint table

catalog: specify the catalogue of the joint table

schema: specify the diagram of the joint table

joinColumns: specify the columns (together @JoinColumn) of the join table which refer the primary keys of

the entity owner of the relation (side owner).

inverseJoinColumns: specify the columns (together @JoinColumn) of the joint table which refer the primary

key(s) of the entity not owner (opposite side).

uniqueConstraints: specify the unique constraints to place in the table. This attribute is used only if the

generation of the table is activated.


In the absence of any parameter of the annotation @OneToOne, the link between the two entities will be made
with a column of joint (second solution) in the owner entity. The name of this one will be the result of the
concatenation of the name of the relational property with the name of the primary key of the other entity.
Concretely, in the example used previously, the owner entity User definite the named persistent property
accountInfo; the primary key of AccountInfo being id, the name would be accountInfo_id.
1.4.6.4. One To Many and Many To One
A relation One To Many, and respectively Many To One, is used to bind to a unique instance of an entity A,
a group of authorities of an entity B. For example, a person has several bank accounts, but a bank account
belongs only to only one person. In our following examples, a user can have several wallets of actions, but a
wallet is dependent only on one user.
An association Many To One is defined on a property with the annotation @ManyToOne. In the case of a

42
http://www.supinfo.com

bidirectional relation, the other side must use the annotation @OneToMany. The attributes of these two
annotations correspond to those of the annotation @OneToOne.
[CODE:java]@Entity
public class Portfolio {
//...
private User user;
@ManyToOne
@JoinColumn(name = "user_fk")
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
@Entity
public class User implements Serializable {
//...
private Collection<Portfolio> portfolios;
@OneToMany(mappedBy = "user")
public Collection<Portfolio> getPortfolios() {
return portfolios;
}
public void setPortfolios(Collection<Portfolio> portfolios) {
this.portfolios = portfolios;
}
}

The entity Portfolio, being the part of the relation having a cardinality of 1, defines a User property user. On the
other hand, the entity User, part of the relation to cardinality N, declare a property multivalued
Collection<Portfolio> portfolios.
Notice the use of the credits which avoid defining the target entity in the definition of our relation. If you do not
wish to use them, then you will have to specify the target of your relation with the attribute targetEntity of the
annotation @OneToMany.
In the same way that with a relation One to One, it is possible to use a table of association. The way of
proceeding already having been explained previously, we will not return above.
1.4.6.5. Many To Many
The last type of relation available is Many to Many. It can be used to bind instances of two entities between
them. For example, between articles and categories. An article can be associated several categories (cardinality
N) and a category can gather several articles (cardinality m).
For that, it is enough to use multivalued properties on each side of the relation (if this one is bidirectional) and to
annotate them with @ManyToMany. In relational term, this relation imposes the use of a table of association.
[CODE:java]@Entity
public class User {
//...
private Collection<Hobby> hobbies;
@ManyToMany
@JoinTable(name = "USER_HOBBIES",
joinColumns = @JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "hobby_id", referencedColumnName = "id")

43
http://www.supinfo.com

)
public Collection<Hobby> getHobbies() {
return hobbies;
}
public void setHobbies(Collection<Hobby> hobbies) {
this.hobbies = hobbies;
}
}
[CODE:java]@Entity
public class Hobby {
//...
private Collection<User> users;
@ManyToMany(mappedBy="hobbies")
public Collection<User> getUsers() {
return users;
}
public void setUsers(Collection<User> users) {
this.users = users;
}
}

Here, each User user has a whole of hobbies Hobby. And conversely, each hobby Hobby can be related to
several User users.
1.4.6.6. Cascading operations
The annotations @OneToOne, @OneToMany, @ManyToOne and @ManyToMany have the attribute cascade. This
one specifies the operations to be carried out in cascade. The cascade means that operation applied to an entity is
propagated with the relations of this one. For example, when a user is removed, its account is also.
There are 4 possible operations on the entities: addition, modification, suppression, reloading. These operations
are gathered in the CascadeType enumeration.

CascadeType.PERSIST: automate the recording of the entities related to the association marked during the
recording of the entity owner (method persist()).

CascadeType.MERGE: automate the recording of the modifications of the entities related to marked
association, during the recording of the modifications of the entity owner (method merge()).

CascadeType.REMOVE: automate the suppression of the entities related to marked association, during the
suppression of the entity owner (method remove()).

CascadeType.REFRESH: automate recharging (side bases data) entities related to marked association, during
the recharging of the entity owner (method refresh()).

CascadeType.ALL: cumulate the 4 types of cascade.

Warning
According to the specification, the CascadeType.REMOVE type can be applied only to associations
"One to One" or "One to Many". The use of this type for other associations is not portable.
For example, on the relation between User and Portfolio, it is logical to record or remove the wallets when the
user is respectively recorded or removed. Here the code corresponding:
44
http://www.supinfo.com

[CODE:java]@OneToMany(
cascade = { CascadeType.REMOVE, CascadeType.PERSIST },
mappedBy = "user"
)
public Collection<Portfolio> getPortfolios() {
return portfolios;
}

In the same way, the relation One to One between User and AccountInfo obliges to safeguard, update and
destroy AccountInfo when these operations are carried out on the instanct of User corresponding. Here the code
corresponding:
[CODE:java]@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
public AccountInfo getAccountInfo() {
return accountInfo;
}

The use of the mechanism of cascade is a real simplification for the developer. Indeed, it does not have to
manage the loops of suppression any more, modification... However, this tool must be used judiciously and with
parsimony. Indeed, a too important use of this mechanism can very quickly harm the performances of the
application.
1.4.6.6.1. Relationnal sample
This bean integrates a relation with another bean of the type: ManyToOne. This relation highlights a field of the
Country type.
The use of the relational annotations describes more in detail the relation:

@ManyToOne defines the type of the relation (ManyToOne)

@JoinColumn defines the column of joint for this relation


[CODE:java]package com.society.stockmanager3.entities.beans;
import java.io.Serializable;
import javax.persistence.Entity;
import javax.persistence.GeneratorType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
@Entity
@Table(name = "CITY")
public class City implements Serializable {
protected int id;
protected String name;
protected Country country;
public City() {
}
public City(String name) {
this.name = name;
}
@Id(generate = GeneratorType.AUTO)
public int getId() {
return id;
}

45
http://www.supinfo.com

public void setId(int id) {


this.id = id;
}
@ManyToOne(optional = false)
@JoinColumn(name = "countryId")
public Country getCountry() {
return country;
}
public void setCountry(Country country) {
this.country = country;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

1.4.6.7. One Many to Many or two One to Many ?


A relation Many to Many is the regrouping of two relations One to Many. Indeed, the relation Many to
Many uses a simple table of joint containing the primary keys on the two sides of the relation.
What happen if we wish to add properties to this relation? For example, when an order gathers products, those
can also be used in several orders. We then find ourselves in the case of a relation Many to Many. However, it
is generally useful to add a property concerning, for example, the quantity of the desired product.
The use of the annotation @ManyToMany does not allow the insertion of additional properties the relation
between the two objects. It is then necessary to use a double connection One to Many and intermediate Entity
Bean. In our example, we have Entity Bean following: Order, Product and OrderLine, respectively representing an
order, a product and the lines of the orders. Here respective codes:
[CODE:java]@Entity
@Table(name="ORDERS")
public class Order {
private int id;
private Date orderDate;
private Collection<OrderLine> orderLines;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Date getOrderDate() {
return orderDate;
}
public void setOrderDate(Date orderDate) {
this.orderDate = orderDate;
}
@OneToMany(mappedBy = "order", cascade = {CascadeType.REMOVE})
public Collection<OrderLine> getOrderLines() {
return orderLines;
}

46
http://www.supinfo.com

public void setOrderLines(Collection<OrderLine> ol) {


this.orderLines = ol;
}
}
[CODE:java]@Entity
public class Product {
private int id;
private String name;
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}

The classes Order and Product are Entity Bean as we could describe them in the first parts.
Entity Bean OrderLine is the central point of the relation. It gets the two properties product and order
respectively related to Entity Bean Product and Order. Moreover, if an autogenerated unique primary key would
simplify the work of the developer, it is more judicious to work with a composite primary key. Indeed, the
regrouping of the primary keys of Product and Order are a good candidate for a primary key, since an order
cannot have the same product twice (in this case there it is enough to increment the quantity). We must then
create a OrderLinePk class to define this composite primary key. This one contains two properties orderId and
productId respectively representing the id of Order and Product.
The annotation @Embeddable declared below makes it possible to declare an entity in time that key composite
primary education.
[CODE:java]@Embeddable
public class OrderLinePk implements Serializable {
private static final long serialVersionUID = 1L;
private int orderId;
private int productId;
protected OrderLinePk() {
}
public OrderLinePk(int orderId, int productId) {
this.orderId = orderId;
this.productId = productId;
}
public int getOrderId() {
return orderId;
}
public void setOrderId(int orderId) {
this.orderId = orderId;

47
http://www.supinfo.com

}
public int getProductId() {
return productId;
}
public void setProductId(int productId) {
this.productId = productId;
}
public int hashCode() {
return orderId ^ productId;
}
public boolean equals(Object that) {
return (that instanceOf OrderLinkPk && orderId == productId);
}
}

Why we use the methods hashCode() and equals() above? They are used for calculter a value based on the
contents of the instance and to compare this one with others.
[CODE:java]@Entity
@IdClass(OrderLinePk.class)
public class OrderLine {
private Product product;
private Order order;
private int quantity;
public OrderLine() {
}
public int getQuantity() {
return quantity;
}
public void setQuantity(int quantity) {
this.quantity = quantity;
}
@ManyToOne
@JoinColumn(name="orderId",
optional=false,
insertable=false,
updatable=false
)
public Order getOrder() {
return order;
}
public void setOrder(Order order) {
this.order = order;
}
@ManyToOne
@JoinColumn(name="productId",
optional=false,
insertable=false,
updatable=false
)
public Product getProduct() {
return product;
}
public void setProduct(Product product) {
this.product = product;
}

48
http://www.supinfo.com

@Id
public int getProductId() {
return getProduct().getId();
}
@Id
public int getOrderId() {
return getOrder().getId();
}
public void setOrderId(int orderId) {
getOrder().setId(orderId);
}
public void setProductId(int productId) {
getProduct().setId(productId);
}
}

We use the annotation @IdClass in order to specify the class of the primary key used. The getters getProductId()
and getOrderId() ondefine those of the OrderLinePk class. However, they respectively turn over the primary key
of the dependent order Order and that of the dependent product Product.
That raises a problem: the columns orderId and productId are already used to refer in the relations Many to One.
They are used at the same time as primary key and foreign key! The supplier of entities encounters a problem: to
assign the primary key and the foreign keys. To specify that we do not wish to assign the foreign keys
automatically, it is necessary to assign the value false to the attributes insertable and updatable of the annotation
@JoinColumn.
1.4.6.8. The heritage
Here 3 possible relational types of mappings:

A single table by hierarchy of class.

A table by concrete class.

A separation of the specific fields of a class girl in a separate table of the table relationship. A junction is then
made for instancier the class girl.
The examples of this part will use two Entity Bean: Bond and Stock which inherit both Entity Bean
FinancialProduct (abstract class).

Warning
Only one primary key must be defined in a hierarchy. Here, the primary key is in the root class
FinancialProduct.

49
http://www.supinfo.com

We will describe the possibilities of each one of these configurations, like their advantages and disadvantages.
The goal is to give you the elements enabling you to make the best choice according to various situations'.
For each case, we will study the annotations used and the generated relational structure.
1.4.6.8.1. A table for a hierarchie of class
In this strategy, all the classes of the hierarchy are mapped in same and unique table. The type of heritage used
is specified on the level of root Entity Bean by the annotation @Inheritance.
[CODE:java]@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
name="financialproduct_type",
discriminatorType=DiscriminatorType.STRING,
length=10
)
public abstract class FinancialProduct {
private int id;
//...
@Id
@GeneratedValue(strategy=GeneratorType.AUTO)
public int getId(){
return id;
}
//...
}

The only attribute of this annotation is strategy. It allow to specify the type of strategy to use with the
InheritanceType enumeration. To define a heritage using the strategy "unique table", it is the value
InheritanceType.SINGLE_TABLE which will be used.
However, this strategy requires a column allowing to differentiate the types of entity of the hierarchy. It is
necessary to use the annotation @DiscriminatorColumn to specify the details of this column. The attributes of this
annotation are:

name: name of the column of discrimination

discriminatorType: discriminator class to be used defined by the enumeration. Possible values are INTEGER,
CHAR and STRING.

length: size of the column for the discriminator at the root of the string.

columnDefinition: SQL fragment to be used for the declaration of the column (used during the generation of the

tables by the container).


The concrete children classes can specify the discriminatory value with the annotation @DiscriminatorValue. The
default value of a discriminator of the type STRING contains the name of the class of Entity Bean. Thus, the
contents of the discriminatory column contain Bond if the stored EntityBean is of Bond type, and Stock if its
type is Stock. For the other types of discriminator, the supplier uses a specific method to generate automatically
a value for Entity Bean.
[CODE:java]@Entity
@DiscriminatorValue("BOND") // valeur par dfaut
public class Bond extends FinancialProduct {
private double rate;

// taux de rendement de lobligation

50
http://www.supinfo.com

private int monthDuration; // nombre de mois que dure lobligation


//...
@Basic
public double getRate(){
return rate;
}
@Basic
public int getMonthDuration(){
return monthDuration;
}
//...
}
[CODE:java]@Entity
@DiscriminatorValue("STOCKOPTION")
public class Stock extends FinancialProduct {
// ...
}

Here the result at the database level (one table for two entities):

This strategy provides an important profit of performance, because no joint is carried out. However, the data use
more place because the whole of the columns is not always used (according to the type of recorded data). Here,
rate has a value null when the recording corresponds to a Stock Entity Bean.
1.4.6.8.2. One table by concrete class
The second strategy presented here is one table by concrete class. In this case, each concrete class Entity Bean
is related to its own table. That means that all the properties of the class (including the inherited properties) are
included in the table related to this entity.
Concretely, on our example, that means that the table FinancialProduct is not created nor not used. Entity Bean
Stock and Bond which inherit the FinancialProduct class are mapped respectively on the tables Stock and
Jump; each one of these tables integrating the properties defined in FinancialProduct.
To specify this strategy, it is necessary to specify the strategy defined by InheritanceType.TABLE_PER_CLASS
for the annotation @Inheritance.
[CODE:java]@Entity
@Inheritance (strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class FinancialProduct {
//...
}

The children classes Bond and Stock have simply to inherit FinancialProduct.
[CODE:java]@Entity
public class Stock extends FinancialProduct {
//...

51
http://www.supinfo.com

Here is the result in the database:

The major advantage of this configuration is during insertion because the addition is made only in one table. In
the same way, the selection of a concrete type (here Bond or Stock) is optimized. Indeed, SELECT relates to only
one table.
The main disadvantage is the heaviness of the polymorphic requests (selection on the whole of
FinancialProduct, for example). Indeed, the data base must use instruction SQL UNION in order to gather the
recordings located in the two tables.
The other disadvantage is the duplication of the columns in each table of Entity Bean; DataBase Administrators
never appreciate this kind of practice.
1.4.6.8.3. One table for a specific part of data
In this last strategy, the class root of the entities is represented by a table. Each children class is related to its
own separate table containing the specific properties of that one.
The link between the tables child and the table root is made with the primary keys. Indeed, the primary key of
the class girl is related to that of the class relationship. Thus, a recording of the table Stock or Bond whose
value of the primary key is 15, is related to a recording of the table FinancialProduct having value 15 for the
primary key.
The heritage is declared here with the InheritanceType.JOINED strategy.
[CODE:java]@Entity
@Inheritance (strategy=InheritanceType.JOINED)
public class FinancialProduct {
//...
}

The children classes Bond and Stock do not need another annotation only @Entity:
[CODE:java]@Entity
public class Bond extends FinancialProduct {
//...
}
[CODE:java]@Entity
public class Stock extends FinancialProduct {
//...
}

Here the result at the database level (place optimization tacken by the data):

52
http://www.supinfo.com

The advantage of this strategy is to have a clearly relational model. It is the ideal model for the dBa (not of
loss of memory because all the fields are used,...). But is also to provide a good support of polymorphism. Thus,
when the client wishes to recover all Entity Beans of the FinancialProduct type, generated request SQL will result
in a simple SELECT * FROM FinancialProduct....
However, the disadvantage is that it requires the use of several joints between the tables during recovery of data.
In the case of important hierarchies (great depth of the heritage) that can involve bad performances.

Warning
Toplink, the GlassFish presistence provider, doesn't supports the joined inheritance type.
1.4.6.8.4. Summary of the methods of mapping of the heritage
Here a summary of the advantages an disadvantages of the differents strategies:

Table 1.7. Advantages and disadvantages of the differents mapping strategies


Strategy

SINGLE_TABLE

Advantages

No joint, therefore very Powerful in insertion


powerful

TABLE_PER_CLASS

Disadvantages

Nonoptimal
of the data

JOINED
Integration of the data
close to the model object

organization Heavy polymorphism to Intensive use of the joints,


manage
therefore
lowers
performance

1.4.7. Persistence unit


The persistence unit is a device making it possible to establish a link between Entity Beans and the database
1.4.7.1. Configuration of a persistance unit
The specification defines a file which gathers the whole of information of persistence. You must name this file:
persistence.xml and to place this file in repertory META INF, to the root of the project.
This file will be read by EJB container during the deployment of the application. The container then creates an
instance of the supplier of persistence with the required parameters.

Warning
You must name correctly the file persistence.xml. If the name does not match, the container will not
associate any context of persistence in the application.
Here the file persistence.xml, parameterized with Hibernate, used in our example:
[CODE:xml]<?xml version="1.0"?>
<persistence version="1.0">
<persistenceunit name="stockmanagerUP">
<jtadatasource>java:StockMainDS</jtadatasource>
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>

53
http://www.supinfo.com

<property name="hibernate.hbm2ddl.auto" value="createdrop" />


<property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect" />
</properties>
</persistenceunit>
</persistence>

Here a description of each mark used:

<persistenceunit> (0N) : declare a unit of persistence

The attribute name assigns a unique name to this unit in your application. The name is used to identify the
unit of persistence during its use with the annotations You will have to define several units of persistence if
you wish to use several data sources.

<jtadatasource> (01) : allows to define name JNDI for the data source to use. This one must be parameterized

on the server and integrate the Transactions.

<provider> (01) : allows to define the class of implementation of the supplier of persistence used in the

application (subclass of javax.persistence.spi.PersistenceProvider). Each unit of persistence uses a unqiue


supplier. You can, in environment Java EE, use the default supplier of the server of application:

JBoss uses Hibernate: org.hibernate.ejb.HibernatePersistence

Oracle
Application
Server
p3.EntityManagerFactoryProvider

GlassFish
(Sun
Application
p3.EntityManagerFactoryProvider

uses

Server

TopLink:

9)

uses

TopLink:

oracle.toplink.essentials.ejb.cm

oracle.toplink.essentials.ejb.cm

KODO: kodo.persistence.PersistenceProviderImpl

<properties> (0N) : This mark allow you to configure the attributes of configuration of the supplier of

persistence. This mark gathers the whole of the properties <property>.


A <property> is defined by a name (attribute name) and a value (attribute value).
A unit of persistence is mapped with a whole of Entity Bean. In a default environment Java EE, the container
analyze the whole of the classes of the JAR file containing the file persistence.xml.
Like theses units of persistence use Hibernate, we can parameterize the engine of persistence with the properties
available (related to Hibernate). We must specify the property hibernate.hbm2ddl.auto with the value update. This
one allow automatically to generate the diagram of the database but also to update it in the event of modification
of the structure of Entity Bean. The diagram will be generated according to the annotations read in the classes of
entities.
The property hibernate.dialect parameter the dialect used by Hibernate to communicate with the data base (here
MySQL). There are some for the majority of the databases available, as one can see it in the package
org.hibernate.dialect:

Table 1.8. List of majors dialects proposed by Hibernate


Database

Class of dialect

MySQL (Inno DB)

org.hibernate.dialect.MySQLInnoDBDialect

54
http://www.supinfo.com

Database

Class of dialect

PostGreSQL

org.hibernate.dialect.PostgreSQLDialect

Oracle

org.hibernate.dialect.OracleDialect

SQL Server

org.hibernate.dialect.SQLServerDialect

HSQLDB

org.hibernate.dialect.HSQLDialect

Derby

org.hibernate.dialect.DerbyDialect

DB2

org.hibernate.dialect.DB2Dialect

1.4.8. Persistence manager


We will describe, in this part, the use of API EntityManager in order to manage the cycle of life of an instance
of Entity Bean.

Note
The access to the data is represented by the operations of addition, reading, modification and
suppression (defined by acronym CRUD: Create Read Update Delete). We generally implements
Pattern DAO to standardize these accesses
In the majority of the cases, the handling of the data with a container EJB is carried out by defining a Bean
Session in "facade".

Note
The design pattern "facade" provides a uniform interface of access to a whole of subsystems. The
application uses a whole of systems without really being aware of it and having the difficulties of use
which each system can induce.
This Beans Session reaches the context of persistence and can then work with the instances of Entity Beans,
with Entity Manager. It is what will be presented in the examples of the following parts.
1.4.8.1. Recovery of Entity Manager
It is possible to let the container give the responsability to inject an instance of Entity Manager at the time of
instanciation of the Bean Session. This method is undoubtedly simplest and most practical.
You must annotate the variable of instance of the type EntityManagerFactory or EntityManager with
@PersistenceContext. This annotation admits several attributes:

name: declare a name local referred on a unit of deployed persistence (local reference towards a unit of

persistence).

unitName: the name of the unit of persistence defines to use to inject EntityManager.

type: indicate the context type of persistence injected ( EXTENDED or TRANSACTION).

Here an example of use within the business application of wallet of actions. Here, EntityManagerFactory, related
to the unit of named persistence stockmanagerUP, is injected.
[CODE:java]@Stateless
@Local({CommonService.class})
public class CommonServiceBean implements CommonService {
@PersistenceContext(unitName="stockmanagerUP")
protected EntityManagerFactory emStockManagerFactory;
}

55
http://www.supinfo.com

The context of persistence is created at the same time as the Bean Session and has the same cycle of life as this
one. It is closed when the Bean Session is destroyed. During all the life of the Bean Session, the instance of
Entity Beans associated with the context of persistence are managed.
1.4.8.2. Persist an entity instance
To record an entity mean to insert it in the database. This operation results in the call of the method
EntityManager.persist(Object o). This one does not apply that to entities yet not recorded in the database.

To record an entity, you must first of all create an instance, then to affect its properties and its relationships to
the desired values, as you can do it with a Java object. Finally, it is enough to call you the method persist().
[CODE:java]User newUser = new User();
newUser.setFirstname("Cyril");
newUser.setEmail("popom@supinfo.com");
entityManager.persist(newUser);

Once this method called, the instance newUser becomes managed and its insertion in database is put in the queue
of Entity Manager. If the method persist() is called in a transaction, insertion in data base can be immediately
made or put in queue until the transaction finishes. That depends on the mode used for synchronization at the
data base.
It is not possible to call the method persist() apart from a transaction only if Entity Manager is of wide type
(EXTENDED). We will not have time to describe this operating mode more.
1.4.8.3. Recovery entities
Once the objects are saved, it is important to be able to recover them. There are two ways of recovering these
objects of the database. We will detail the recovery of objects starting from their primary key. The other solution
consists in working with requests EJBQL (see the following chapter).
Entity Manager proposes the following method:
[CODE:java]<T> T find(Class<T> entity, Object primaryKey)

The use of the generics avoids having to cast the return value. However differences exist.
The method find() return null if no entity is associated with the required primary key. It also initializes the basic
states of the lazyloading associated the properties.
[CODE:java]User user1 = entityManager.find(User.class, 1);
if (user1 == null) {
// ...
}

1.4.8.4. Modify entities


There are two ways of modifying an entity. Either to load it from the database and the modifications within the
transaction or you apply you to him wish to update a detached object and in this case there you must use the
method merge().
When you recover an entity with find() or with a request, this one become managed until the closing of the
context of persistence. You can then change the properties of this instance, the modifications will be
synchronized automatically.
[CODE:java]public void changeUserEmail(int userId, String email) {
User currentUser = entityManager.find(User.class, userId);
currentUser.setEmail(email);
}

56
http://www.supinfo.com

In the preceding example, Entity Manager must be associated to the current transaction if it is wished that the
modifications be recorded. Those are really affected in database when the transaction finishes or that the method
flush() is called explicitly.

The other solution is to use when you wish to amalgamate the modifications made on an object detached
towards the context of persistence. It is the case, for example, when an entity leaves container EJB towards
another application (Web or rich Customer). You must use the method EntityManager.merge() in order to attach
the instance to the context of persistence. Let us imagine that a rich client calls the method findUser() following:
[CODE:java]@PersistenceContext
private EntityManager em;
public User findUser(int userId) {
return em.find(User.class, userId);
}

The context of persistence is closed after the execution of the method findUser() (we suppose that the Bean
Session uses management of the transactions). From there, returned instance is detached and the modifications
applied are not synchronized any more. If the customer application wishes to record the modifications made
locally, it must return the authority to the Bean Session.
[CODE:java]User returnedUser = adminService.findUser(2);
returnedUser.setEmail("nouvelleemail@supinfo.com");
adminService.updateUser(returnedUser);

In this case there, the method updateUser() must use EntityManager.merge() in order to attach the instance to
the context.
[CODE:java]@PersistenceContext
private EntityManager em;
public void updateUser(User user) {
User attachedUser = em.merge(user);
}

Various behaviors apply according to the context in which you call the method merge().
If Entity Manager does not contain an instance of the entity with the same primary key, then it creates a
complete copy of the object passed in argument and return it. This copy is then attached to the context of
persistence and the modifications made above are synchronized with the data base.
If Entity Manager holds already an instance of the entity having the same primary key, then the contents of the
parameter (user here) are copied in the attached instance.
In both cases, the parameter user of the method updateUser() remains detached and is not synchronized with the
database. This is why the developer must work with the instance turned over by the method merge() if it must
make other modifications on the entity.
1.4.8.5. Delete an instance
The EntityManager.remove() method is used to ask for the suppression of an entity of the database. We speak
57
http://www.supinfo.com

about "request" because the suppression is not effective immediately but only with the call of the method flush()
or at the closing of the context of persistence. Meanwhile, it is possible to cancel the suppression.

[CODE:java]@PersistenceContext
private EntityManager em;
public void removeUser(int userId) {
User userToRemove = em.find(userId);
em.remove(userToRemove);
}

The call to the method remove() detaches the entity of the context of persistence. To cancel this suppression (in
the same context of persistence) it is necessary to call the method persist() in order to attach the instance to the
context.
1.4.8.6. Reload entities
If you know that the instance of an entity does not reflect the values of the database , you can use the method
EntityManager.refresh() in order to reload the entity since the data base. This operation override all the
modifications which could be made to the entity.
[CODE:java]@PersistenceContext
private EntityManager em;
public void workOnUser(int userId) {
User user = em.find(userId);
user.setEmail("nomail@supinfo.com");
em.refresh(user);
}

In the last example, the email is not modified because of the call to the method refresh().
1.4.8.7. Synchronization with database
When you call the methods persist(), merge() or remove(), the changes are not synchronized immediately. This
synchronization is established automatically at the end of a transaction or when Entity Manager decides to
empty its queue. However, the developer can force synchronization by explicitly calling the method flush() of
Entity Manager.

Warning
flush() and commit() are two different operations! flush() sends requests SQL to the data sources whereas
commit() validates the transaction on the level of these sources.

1.4.9. Management of the cycle of life of an entity


The cycle of life of an instance of Entity Bean includes 4 distinct states which it is necessary to know and
understand. Here a description of these various states:
new : mean that the instance isnt associated to a persistent context. This state results from the instanciation
of Entity Bean with new.
managed : mean that the instance has an identity associated with the persistent context. An instance is
generally in this state when it comes to be recorded, modified or to be recovered.

58
http://www.supinfo.com

detached : mean that the instance is not associated any more with the persistent context from where it
comes. It is generally the case when the instance is initialized in the container then sent to another third
(presentation, Web...).
removed : mean that the instance has an identity associated with a persistent context but which it is
intended to be withdrawn from the data base.

The call of the methods related to the cycle of life is carried out by the container. We speaksabout callback
methods (methods of return). However, the study of these methods would leave of the framework of this
essence.
1.4.9.1. Detached entities
It is necessary to handle carefully the persistent fields marked by fetch=LAZY when Entity Bean is handled
apart from the context of persistence. Indeed, the marked collections lazy are not charged by the container.
But, in the case of a detached entity, if the collection were not charged in the container with EJB, it will be
impossible to reach the property apart from the container
To resolve that, we should be sure that all the properties of the entity used at the customer are initialized before
the object is detached from the context of persistence. For that, it is enough to ask the loading of the data when
the entity is still managed.
[CODE:java]User user = entityManager.find(User.class, userId);
user.getPortfolios().size();
user.getCVContent();

In this example, the loading of the collection is launched at the same time than the call to the method size() of
this one. In the same way, the loading of the property cvContent is carried out at the same time than the access
to this one.

Warning
The dynamic loading functions only on one managed entity !
Another solution consists in using requests EJBQL with explicit joints to recover the already initialized entities.
For that, it is necessary to use key word FETCH JOIN in the request (see the following chapter).

59
http://www.supinfo.com

1.5. EJB-QL
1.5.1. What EJBQL?
EJBQL (Undertaken JavaBean Query Language) is a specification of query language. Integrated into system
EJB, this query language has several advantages. First of all, its the portability which enables him to be used
with identical between the various versions of language SQL. Indeed, this one rests on an abstraction of
language SQL and is translated into true SQL at the time of its execution. In addition, EJBQL makes it
possible to use the objects of Entity Beans of the application directly in the requests, for more facility. In the
same way, the supplier of persistence will translate these requests into true SQL at the time of the execution.
The finality of this language is to some extent identical to that of the manager of persistence, which offers,
indeed, the possibility of carrying out requests of the INSERT type, UPDATE or DELETE.

1.5.2. The abstract diagram


In order to work with the entities, EJBQL is based on the abstract diagram of Entity Bean. The abstract diagram
is an internal representation of the entities and their relations. However, even if this term seems complex at first
sight, one usually assimilates it in the name of Entity Bean.
With specification EJB 3, one generally uses the annotations. One can then specify the name of reference by the
attribute name of the annotation @Entity.
[CODE:java]@Entity(name = "AccountInfo")
public class AccountInfo {
// ...
}

By defect, the name of the class of Entity Bean will be used. For example, the diagram abstracted owing to lack
of Entity Bean, defined by the class To use, is To use.
The abstract term distinguishes this diagram from the physical diagram of the data base. In a relational data
base, the physical diagram corresponds to the structure of the tables and columns. In EJBQL you work with the
abstract diagrams and not with the name of the tables of your physical diagram, as represents it the following
diagram.

Note
We advise you to draw a sketch of the diagram abstracted before writing your requests.

In short, it should be retained that it acts of an abstract representation of Entity Bean, used by EJBQL to sail
between the persistent and relational properties.

1.5.3. Writing of requests


Before returning in the innumerable details of this language, here a first simple example which will enable you
to more easily include/understand the continuation of the explanations.

60
http://www.supinfo.com

[CODE:java]String queryString = "SELECT user FROM User AS user";


Query query = entityManager.createQuery(queryString);
List<User > allUsers = query.resultList();
for (User U: allUsers) {
// Work on the user...
}

The preceding example uses three different concepts:

Language EJB-QL

Entity manager

API Query
This one turns over the whole of the authorities of Entity Bean User in a list. This one can then be traversed by a
foreach. The details of use of these elements are explained throughout this part.
According to the salesmen, it is possible to journalize (logs) requests SQL carried out by the manager of
persistence. For example, it is enough to add the property hibernate.show_sql with the value true if you use
the engine of Hibernate persistence. We will try to the maximum to illustrate the requests of example with their
correspondence SQL.

Warning
Correspondence SQL was carried out starting from tests carried out with the supplier Hibernate and a
data base MySQL.

1.5.4. Fundamental of the language


A request EJBQL can fill a task of selection (SELECT), modification (UPDATE) or suppression (DELETE).
A request EJBQL is similar with SQL, with the following clauses:

SELECT: list Entity Beans and the properties turned over by the request.

FROM: Entity Beans defines used. Those must be declared via the expression HAVE.

WHERE: allows to apply search criteria. It is possible to specify Java types as well there having their
equivalent in the data bases (String, Integer, Double...) but also Entity Beans. In this last case, at the time of
the passage in native request, the criterion will apply to the primary key.
Of course, others could be added, as we will see it, but those are quasi systematically used to recover data.
The operator "." is used to sail between the properties and the relations of Entity Beans. For example, in order to
recover the user having a wallet of actions, one can represent navigation in the following way:
[CODE:sql]SELECT portfolio FROM Portfolio AS portfolio WHERE portfolio.user.id = 5

Correspondence in SQL :
[CODE:sql]select portfolio0_.id as id38 _, portfolio0_.name as name38 _, portfolio0.user_fk as user3_38 _ from Portfolio
portfolio0 _
where portfolio0_.user_fk = ?

It is guessed rather clearly that the use of "." is similar, in this example, to call the method Portfolio.getUser()

61
http://www.supinfo.com

Warning
Character of termination " ; "of requests SQL does not have to be used, under sorrow which
PersistanceException is launched.
1.5.4.1. Requests SELECT
The most used request is undoubtedly SELECT, the request of research. The instruction to be used is SELECT
like illustrates it the following example, where all the users are selected:
[CODE:sql]SELECT usr FROM User AS usr
[CODE:sql]select user0_.id as id21_, user0_.address_fk as
address8_21_, user0_.password as password21_, user0_.lastName as lastName21_,
user0_.firstName as firstName21_, user0_.login as login21_, user0_.sex as
sex21_, user0_.birthDate as birthDate21_ from XUser user0_

There are many similarities with language SQL. However, it should well be understood that the difference
comes owing to the fact that EJBQL is directed object. In the preceding example, To use corresponds to the
abstract diagram of Entity Bean User and usr corresponds to one alias (as in SQL).
The preceding example works directly with the User object, however it is sometimes practical to recover only
the id, or the name, or the first name... With EJB 3, it is possible to specify the properties which one wishes to
recover. It is enough to specify them in clause SELECT.
[CODE:sql]SELECT user.id, user.lastName FROM User AS user
[CODE:sql]select user0_.id as col_0_0_, user0_.firstName as col_1_0_ from XUser user0_

1.5.4.2. Requests DELETE and UPDATE


These requests will provide a whole of operations to modify or remove Entity Bean. Their common
characteristic is to have only one entity in clause FROM. Thus, if you wish to remove or modify recordings of
several different Entity Bean, you must carry out several requests. Here two examples showing the use of these
requests.
[CODE:sql]DELETE FROM User AS user WHERE user.id = 5
[CODE:sql]delete from XUser where id=?
[CODE:sql]UPDATE User AS user
SET user.firstName = "Durand"
WHERE user.id = 1
[CODE:sql]update XUser set firstName=? where id=?

Clause DELETE of EJBQL does not support the suppression in cascade. Indeed, even if the relation is
configured with CascadeType.REMOVE or CascadeType.ALL, it will be necessary all the same to manually
write their withdrawal of the data base. In this request DELETE, we are likely to receive exceptions if Entity
Bean User would have relations. We have three possibilities then:

To use the manager of persistence which applies the suppression in cascade.

To explicitly write all requests EJBQL of suppressions in the good order.

To use the possibilities of the data base and to manage the suppression cascade about it on the level of this
one.
In this last case, its possible to use the expression ON DELETE CASCADE for, for example, the data bases of
the type MySQL version 5 and the engine of InnoDB storage.
You will have, before, to check that the constraints of modifications in cascade were indeed applied. Here an

62
http://www.supinfo.com

extract of code SQL to be used:


[CODE:sql] Contraintes pour la table `AccountInfo`
ALTER TABLE `AccountInfo`
ADD CONSTRAINT `fk1` FOREIGN KEY (`id`) REFERENCES `xuser` (`id`) ON DELETE
CASCADE;
Contraintes pour la table `FINANCIALPRODUCT`
ALTER TABLE `FINANCIALPRODUCT`
ADD CONSTRAINT `fk2` FOREIGN KEY (`portfolio_fk`) REFERENCES `portfolio`
(`id`) ON DELETE CASCADE;
Contraintes pour la table `Portfolio`
ALTER TABLE `Portfolio`
ADD CONSTRAINT `fk3` FOREIGN KEY (`user_fk`) REFERENCES `xuser` (`id`) ON
DELETE CASCADE;

In this way, at the time of the removal of a user, all his wallets, financial products, and information will be
automatically removed.
1.5.4.3. Clause WHERE
The permissions included in clause WHERE exist for the majority in a similar form with that which one can use
in SQL. Here a list summarizing those most usually used:

BETWEEN: conditional operator allowing to restrict the results according to an interval. The following
example selects all the users having an identifier of 1500 to 2000.
[CODE:sql]SELECT user FROM User AS user
WHERE user.id BETWEEN 1500 AND 2000
[CODE:sql]select user0_.id as id4_, user0_.address_fk as
address8_4_, user0_.password as password4_, user0_.lastName as lastName4_,
user0_.firstName as firstName4_, user0_.login as login4_, user0_.sex as
sex4_, user0_.birthDate as birthDate4_ from XUser user0_ where user0_.id
between ? and ?

LIKE: allows to compare the value of a field with a specified reason. The following request recovers, for
example, all the accounts having a first name starting with "Jean".
[CODE:sql]SELECT user FROM User AS user
WHERE user.firstName LIKE 'jean%'
[CODE:sql]select user0_.id as id4_, user0_.address_fk as
address8_4_, user0_.password as password4_, user0_.lastName as lastName4_,
user0_.firstName as firstName4_, user0_.login as login4_, user0_.sex as
sex4_, user0_.birthDate as birthDate4_ from XUser user0_ where
user0_.firstName like ?

The reason is built with two special characters. First is "%" and it is used for a number of indefinite natures.
The second, "_", represent only one character. If your character string would use really these two characters,
you have at your disposal the escape character "\". Here some examples of use:

firstname LIKE `_axime' will return the entries such as Maxime, Aaxime...

firstname LIKE ` Ma% ' will return the entries with Marc, Martine, Maxime...

misc LIKE `%\_%' will return the entries containing the character ` _ ', such as ` java_bean', ` java _ ', `_java'

or ` _ '

63
http://www.supinfo.com

IN: test a membership of a list of character strings. The following request recovers, for example, all the
contacts located in France, Spain, and Belgium
[CODE:sql]SELECT user FROM User AS user
WHERE user.address.country IN ('France', 'Spain', 'Belgium')
[CODE:sql]select user0_.id as id4_, user0_.address_fk as
address8_4_, user0_.password as password4_, user0_.lastName as lastName4_,
user0_.firstName as firstName4_, user0_.login as login4_, user0_.sex as
sex4_, user0_.birthDate as birthDate4_ from XUser user0_, Address address1_
where user0_.address_fk=address1_.id and (address1_.country in ('France' ,
'Espagne' , 'Belgique'))

IS NULL: test if a value is null. It acts of the default value defined when a field was not indicated. The
following request returns, for example, the recordings where the login was not specified.
[CODE:sql]SELECT user FROM User AS user
WHERE user.login IS NULL
[CODE:sql]select user0_.id as id21_, user0_.address_fk as
address8_21_, user0_.password as password21_, user0_.lastName as lastName21_,
user0_.firstName as firstName21_, user0_.login as login21_, user0_.sex as
sex21_, user0_.birthDate as birthDate21_ from XUser user0_ where user0_.login
is null

MEMBER OF: test the membership of an authority to a collection, just like the method contains() of the
interface java.util.Collection. The following example recovers the users having the wallet passed in parameter
(we will further see the passage of the parameters in this chapter).
[CODE:sql]SELECT user
FROM User AS user
WHERE ?1 MEMBER OF user.portfolios
[CODE:sql]select user0_.id as id21_, user0_.address_fk as
address8_21_, user0_.password as password21_, user0_.lastName as lastName21_,
user0_.firstName as firstName21_, user0_.login as login21_, user0_.sex as
sex21_, user0_.birthDate as birthDate21_ from XUser user0_ where ? in (select
portfolios1_.id from Portfolio portfolios1_ where
user0_.id=portfolios1_.user_fk)

EMPTY: test if a collection is empty. For example, we here will turn over the list of the users not having any
wallet of action.
[CODE:sql]SELECT user
FROM User AS user
WHERE user.portfolios IS EMPTY
[CODE:sql]select user0_.id as id21_, user0_.address_fk as
address8_21_, user0_.password as password21_, user0_.lastName as lastName21_,
user0_.firstName as firstName21_, user0_.login as login21_, user0_.sex as
sex21_, user0_.birthDate as birthDate21_ from XUser user0_ where not (exists
(select portfolios1_.id from Portfolio portfolios1_ where
user0_.id=portfolios1_.user_fk))

NOT: opposite the result of the condition. We can use it with preceding operators (NOT BETWEEN, NOT
LIKE, NOT IN, IS NOT NULL...).
1.5.4.4. Clause ORDER BY
Clause ORDER BY makes it possible to arrange by order the results of a request, starting from one or more
fields by using the alphanumeric order then alphabetical. To know exactly the implementation of this function, it
is necessary to refer to the handbook of the data base.
The following example turns over the list of the users ordered according to their identifier.
64
http://www.supinfo.com

[CODE:sql]SELECT user
FROM User AS user
ORDER BY user.id ASC
[CODE:sql]select user0_.id as id4_, user0_.address_fk as
address8_4_, user0_.password as password4_, user0_.lastName as lastName4_,
user0_.firstName as firstName4_, user0_.login as login4_, user0_.sex as
sex4_, user0_.birthDate as birthDate4_ from XUser user0_ order by user0_.id

Here what one could recover (according to the data of the database):

Table 1.9. Results of an ORDER BY


ID

First name

Cyril

Frederic

Olivier

Maxime

10

Jean-Baptiste

Key word optional ASC means that the classification is made in an ascending way. To carry out it in a
downward way, DESC should be used (larger with smallest). By defect, it is ASC which is applied.
It is of course possible to combine these criteria. Thus, the following request posts the name by ascending order,
however when two users have the same name, the sorting is done then on the first name, in an increasing way,
then decreasing in the second example.
[CODE:sql]SELECT user
FROM User AS user
ORDER BY user.lastName, user.firstName ASC
[CODE:sql]select user0_.id as col_0_0_, user0_.firstName as
col_1_0_ from XUser user0_ order by user0_.lastName, user0_.firstName ASC
[CODE:sql]SELECT user
FROM User AS user
ORDER BY user.lastName ASC, user.firstName DESC
[CODE:sql]select user0_.id as col_0_0_, user0_.firstName as
col_1_0_ from XUser user0_ order by user0_.lastName ASC, user0_.firstName
DESC

1.5.4.5. Functions of aggregation


The functions of aggregation are used to carry out operations on sets. One finds them in EJBQL via the
following instructions:

avg(): turn over an average by group

count(): turn over the number of recordings sum(): turn over the sum of the values

max(): turn over the highest value

min(): turn over the lowest value

sum(): turn over the sum of the values


For example, you can use the function count() to know the number of users registered in your data base.

65
http://www.supinfo.com

[CODE:sql]SELECT COUNT(user) FROM User AS user


[CODE:sql]select count(user0_.id) as col_0_0_ from XUser user0_

It is also possible to use clause GROUP BY to apply the function of aggregation to a batch of recordings. Here
an example allowing to turn over the number of wallets per user:
[CODE:sql]SELECT user.firstName, COUNT(user.portfolios) AS nbrPortfolio
FROM User AS user
GROUP BY user
[CODE:sql]select user0_.id as col_0_0_,
count(portfolios1_.id) as col_1_0_, user0_.id as id72_, user0_.address_fk as
address8_72_, user0_.password as password72_, user0_.lastName as lastName72_,
user0_.firstName as firstName72_, user0_.login as login72_, user0_.sex as
sex72_, user0_.birthDate as birthDate72_ from XUser user0_ left outer join
Portfolio portfolios1_ on user0_.id=portfolios1_.user_fk group by user0_.id

The results could be as follows, by supposing fictitious data:

Table 1.10.
First name

Portfolios

Cyril

Frederic

Jean-Baptiste

Maxime

Olivier

The interest of GROUP BY in this request is to be able to apply function COUNT() to each user.
Clause HAVING makes it possible to specify criteria, as with clause WHERE, on a column generated by one of
the functions of aggregation. In the following example, we turn over only information when the number of
financial wallets is higher than 2.
[CODE:sql]SELECT user.firstName, COUNT(user.portfolios) AS nbrPortfolio
FROM User AS user
GROUP BY user.firstName
HAVING nbrPortfolio > 2

Note
In accordance with standards SQL, it is necessary to use clause HAVING in order to apply criteria to
the result of a function.
1.5.4.6. To handle the collections with the operator IN
The major part of the relations uses collections. The course of their entries is particularly interesting because
there does not exist in the relational logic of the SQL.
We have for that the operator IN. He must be placed in clause FROM, and makes it possible to declare alias for
the entries of a collection. For example, we can recover the whole of the wallets created, as follows:
[CODE:sql]SELECT portfolio
FROM User AS user, IN (user.portfolios) portfolio
[CODE:sql]select portfolio0_.id as id139_, portfolio0_.name
as name139_, portfolio0_.user_fk as user3_139_ from Portfolio portfolio0_
where portfolio0_.user_fk=?

We gather the elements contained in the collection user.porfolios, in alias " the portfolio ". So the request
gathers the wallets of all the users and the load.
The identifiers in clause FROM are declared of left on the right. When an identifier is declared, one can use it in
the following declarations. The following request recovers all the financial products had by the user having
66
http://www.supinfo.com

identifier 42.
[CODE:sql]SELECT fp
FROM User AS user,
IN (user.portfolios) portfolio,
IN (portfolio.financialProducts) fp
WHERE user.id = 42 AND fp.quantity > 10
[CODE:sql]select financialp2_.id as id104_,
financialp2_.quantity as quantity104_, financialp2_.buyValue as buyValue104_,
financialp2_.productName as productN5_104_, financialp2_.buyDate as
buyDate104_, financialp2_.portfolio_fk as portfolio10_104_,
financialp2_.monthDuration as monthDur7_104_, financialp2_.rate as rate104_,
financialp2_.price as price104_, financialp2_.financialproduct_type as
financia1_104_ from XUser user0_ inner join Portfolio portfolios1_ on
user0_.id=portfolios1_.user_fk inner join FINANCIALPRODUCT financialp2_ on
portfolios1_.id=financialp2_.portfolio_fk where user0_.id=?

This operator allows to directly select the elements of a relation and to work with. In the preceding example, the
request turns over FinancialProduct having a quantity higher than 10 of the user of id 42 (any confused wallet).
One second function, ELEMENTS, fulfills the same role, but is in clause SELECT. Here a request with a
similar result with the first example.
[CODE:sql]SELECT ELEMENTS(user.portfolios)
FROM User AS user
[CODE:sql]select portfolio0_.id as id139_3_, portfolio0_.name as name139_3_,
portfolio0_.user_fk as user3_139_3_, user1_.id as id140_0_, user1_.address_fk
as address8_140_0_, user1_.password as password140_0_, user1_.lastName as
lastName140_0_, user1_.firstName as firstName140_0_, user1_.login as
login140_0_, user1_.sex as sex140_0_, user1_.birthDate as birthDate140_0_,
address2_.id as id143_1_, address2_.country as country143_1_, address2_.city
as city143_1_, address2_.numero as numero143_1_, address2_.street as
street143_1_, address2_.zipCode as zipCode143_1_, accountinf3_.id as
id142_2_, accountinf3_.accountId as accountId142_2_, accountinf3_.cardNumber
as cardNumber142_2_, accountinf3_.amount as amount142_2_ from Portfolio
portfolio0_ left outer join XUser user1_ on portfolio0_.user_fk=user1_.id
left outer join Address address2_ on user1_.address_fk=address2_.id left
outer join AccountInfo accountinf3_ on user1_.id=accountinf3_.id where
portfolio0_.id=?

1.5.4.7. Joints
The joints make it possible to handle the relations between the entities. We will see that the functionalities
available are multiple and will be able to adapt to many needs. To illustrate this declaration, we present the
recovery of the wallets of actions, had by a user, various manners.
By using the style thta, with the relation between primary and key keys foreign:
[CODE:sql]SELECT user.firstName, ai.cardNumber
FROM User AS user, AccountInfo AS ai
WHERE u.accountInfo.id = ai.id
[CODE:sql]select user0_.firstName as col_0_0_,
accountinf1_.cardNumber as col_2_0_ from XUser user0_, AccountInfo
accountinf1_ where user0_.id=accountinf1_.id

By using the relational properties:


[CODE:sql]SELECT user.firstName, user.accountInfo.cardNumber
FROM User AS user
[CODE:sql]select user0_.firstName as col_0_0_,
accountinf1_.cardNumber as col_2_0_ from XUser user0_, AccountInfo
accountinf1_ where user0_.id=accountinf1_.id

67
http://www.supinfo.com

By using a joint via instruction JOIN:


[CODE:sql]SELECT user.firstName, ai.cardNumber
FROM User AS user
JOIN user.accountInfo AS ai
[CODE:sql]select user0_.firstName as col_0_0_,
accountinf1_.cardNumber as col_2_0_ from XUser user0_ inner join AccountInfo
accountinf1_ on user0_.id=accountinf1_.id

Table 1.11. Results of a JOIN


First name

Card number

Cyril

1111-2222-3333-4444

Ophlie

2222-3333-4444-5555

The turned over results are the same ones for each request with some exceptions. Indeed, the operation of the
joints is subtle. When a User entity does not have a relationship to the AccountInfo entity, the recording will
not be turned over !
1.5.4.7.1. LEFT JOIN
In order to return the recordings of the Account entity, even if they do not have a relation, it is necessary to carry
out a joint known as "open". For that, one uses the instructions LEFT OUTER JOIN or RIGHT OUTER JOIN,
also existing in SQL.
In EJBQL, the expression LEFT JOIN allows systematically to include the first entity in the result of the
request. RIGHT JOIN, as for it, adds the results of the second entity.

Note
Instruction OUTER, used in SQL, became optional.
The following example uses an open joint. The results are then different.
[CODE:sql]SELECT user.firstName, user.lastName, ai.cardNumber
FROM User AS user
LEFT JOIN user.accountInfo AS ai

Table 1.12. Results of a LEFT JOIN


First name

Card number

Cyril

1111-2222-3333-4444

Maxime

2222-3333-4444-5555

Jean-Baptiste

NULL

Indeed, the request from now on took into account the third recording, which does not have a relation with
AccountInfo. This request carries out a "joint open on the left". Here its correspondence in SQL:
[CODE:sql]select user0_.firstName as col_0_0_, user0_.lastName as col_1_0_,
accountinf1_.cardNumber as col_2_0_
from User user0_
left outer join AccountInfo accountinf1_ on
user0_.accountinfo_fk=accountinf1_.id

1.5.4.7.2. INNER JOIN


We previously saw the use of the operator IN. The joint of the type INNER causes the same result. It is
however more familiar with the developers usually using the SQL.
It is enough to use key word INNER JOIN to carry out this type of joint.
[CODE:sql]SELECT p FROM User u INNER JOIN u.portfolios p

68
http://www.supinfo.com

[CODE:sql]select user0_.firstName as col_0_0_,


user0_.lastName as col_1_0_, accountinf1_.cardNumber as col_2_0_ from XUser
user0_ inner join AccountInfo accountinf1_ on user0_.id=accountinf1_.id

The preceding request turns over the whole of the wallets created whatever the user. It is however simpler to use
the operator IN. Here correspondence using IN:
[CODE:sql]SELECT p FROM User u, IN(u.portfolios) p

1.5.4.7.3. FETCH JOIN


We saw previously that it was possible to use a mechanism of the lazy loading. In this case, when the
application reaches a property marked with lazy, the supplier of persistence must charge it.
[CODE:Java]Query query = entityManager.createQuery("SELECT u FROM User u WHERE u.id = :userId");
User user = (User) query.setParameter("userId", 1).getSingleResult();
Iterator<Portfolio> portfoliosIt = user.getPortfolios().iterator();
while(portfoliosIt.hasNext()) {
Portfolio p = portfoliosIt.next();
p.getFinancialProducts().size();
}

This example charges the user of id 1 and initializes its wallets and the associated financial products. That poses
problems of performances however. Indeed, the engine of persistence must carry out a request with line 2 then
for each loading of the associated financial products (line 5). This one operates N+1 requests then (N being the
number of wallet).
To optimize that, it is necessary to use a request EJBQL with a joint of the type FETCH.
[CODE:sql]SELECT U FROM To use U INNER JOIN FETCH u.portfolio p LEFT JOIN FETCH
p.financalProducts
[CODE:sql]select user0_.id have id310_0 _, portfolios1_.id have id309_1 _,
user0_.address_fk have address8_310_0 _, user0_.password have password310_0 _,
user0_.lastName have lastName310_0 _, user0_.firstName have firstName310_0 _,
user0_.login have login310_0 _, user0_.sex have sex310_0 _, user0_.birthDate have
birthDate310_0 _, portfolios1_.name have name309_1 _, portfolios1_.user_fk have
user3_309_1 _, portfolios1_.user_fk have user3_0 __, portfolios1_.id have id0 __ from
XUser user0 _ left outer join Portfolio portfolios1 _ one user0_.id=portfolios1_.user_fk left
outer join FINANCIALPRODUCT financialp2 _ one
portfolios1_.id=financialp2_.portfolio_fk

A joint fetch does not need normally to define alias except when you wish to use the concept of the fetch
recursively.
Thanks to this modification, only one request is carried out. The use of this type of joint in a program is a need
for the optimization and the improvement of the performances. Indeed, it is strongly advised to avoid too much
outward journey and return with the data base.
1.5.4.8. Management of Polymorphism
EJBQL supports polymorphism, i.e. the requests relating to a hierarchy of objects.

69
http://www.supinfo.com

The execution of the following request turns over all the recordings dependent on the FinancialProduct entity
and thus of its subclasses.
[CODE:sql]SELECT fi FROM FinancialProduct AS fi

The collection of result contains objects of the Bond type or Stock, i.e. the concrete types of the hierarchy.
1.5.4.9. Under requests
The underrequests can beings placed in clauses WHERE and HAVING. Like their equivalent SQL, they make it
possible to imbricate the requests. The following example selects the users having more than 3 financial wallets.
[CODE:sql]SELECT user
FROM User user
WHERE (
SELECT COUNT(portfolio)
FROM Portfolio AS portfolio
WHERE portfolio.user=user
GROUP BY user
) >3
[CODE:sql]select user0_.id as id327_, user0_.address_fk as
address8_327_, user0_.password as password327_, user0_.lastName as
lastName327_, user0_.firstName as firstName327_, user0_.login as login327_,
user0_.sex as sex327_, user0_.birthDate as birthDate327_ from XUser user0_
where (select count(portfolio1_.id) from Portfolio portfolio1_ where
portfolio1_.user_fk=user0_.id group by user0_.id)>?

It is noticed that one alias reuses to use of the principal request in the underrequest. One of the principal interests
of the underrequests is to be able to replace the joints, in particular in the requests of the type UPDATE and
DELETE.
The following request removes all the financial products where the user has a id having for value 5:
[CODE:sql]DELETE FROM FinancialProduct AS fp
WHERE fp.portfolio IN (
SELECT portfolio
FROM Portfolio AS portfolio
WHERE portfolio.user IN (
SELECT user
FROM User AS user
WHERE user.login = 5
)
)
[CODE:sql]delete from FINANCIALPRODUCT where portfolio_fk in
(select id from Portfolio portfolio1_ where portfolio1_.user_fk in (select id
from XUser user2_ where user2_.id = 5))

Note
Use the underrequests when you cannot make differently. We advise you to study, initially, the use of
joints or instructions such as IN, ELEMENTS... which are obligatory besides in systems not taking into
account the underrequests.
When under request is likely to turn over several lines, it is then possible to quantify the result having to be
turned over. For that, one uses the expressions:

ALL turns over true if all the results of the request checks the condition.

SOME turns over true so at least a result checks the condition

ANY turns over true if no result checks the condition

70
http://www.supinfo.com

1.5.5. API Query


API Query is the essential point for the junction between the application and the execution of requests EJBQL.
The methods of this one are gathered in the interface javax.persistence.Query. We will progressively detail the
various methods of this one.
The principal interest of this API is to be able to create dynamic requests in the form of simple character strings,
and either a static way in the descriptor of deployment.
There are various means of recovering an object of the Query type. The corresponding methods are gathered in
the EntityManager interface. Here a simple example:
[CODE:java]Query query = entityManager.createQuery("SELECT user FROM User As user");
List<User> listUsers = query.getResultList();

We recover a Query object here via the method createQuery() of EntityManager. It is then enough to call the
method getResultList() to carry out the request and to recover the result of this one.
Here a description of the various traditional methods of the Query interface.
[CODE:java]java.util.List getResultList();

This method carries out the request and turns over the whole of the results of this one. It makes it possible for
example to recover a whole of Entity Beans complete. It is then possible to specify several properties in clause
SELECT in order to recover only certain values of the entity, in the form of table.
[CODE:java]Query query = entityManager.createQuery("SELECT user.id, user.lastName FROM User As user");
List<Object[]> listUsers = query.getResultList();
for(Object[] valueArray : listUsers){
Integer id = (Integer) valueArray[0];
String name = (String) valueArray[1];
}

In this case, the method getResultList() turns over a list of table of object (" Object[ ] ").
[CODE:java]java.lang.Object getSingleResult();

This method carries out the request and turns over a single result. If the number of results is higher than 1, a
NonUniqueResultException exception is raised. Conversely, if no result is found, an exception of the
EntityNotFoundException type is raised.
This method must be used only if you are sure that the request turns over only one single result.
[CODE:java]Query query = entityManager.createQuery("SELECT user FROM User AS user
WHERE user.login = 'durand.dupont'");
User currentUser = (User) query.getSingleResult();

In this example, the property login is single. So we are sure that the method cannot return several results.
[CODE:java]setMaxResults(int max) and setFirstResult(int first)

These two methods respectively define the maximum number of results and the index of the first element to be
turned over.
Those make it possible to limit the results of the request. Indeed, if the request tries to turn over several
thousands of lines, you are likely to quickly reduce the performances of your application. Moreover, one
generally does not work with the whole of the results of only one blow but left by part.
[CODE:java]Query query = entityManager.createQuery("SELECT user FROM User As user");
query.setMaxResults(30);
query.setFirstResults(10);
List<User> listUsers = query.getResultList();

1.6. Conclusion
In this essential about EJB3, we've first seen that they locate in the center of your application, providing lots of

71
http://www.supinfo.com

assets (like the object persistence's one and a functionnal and performant client/server model).
Furthermore, during the setting up of this technology, the code writing is kind of simple and is very well
inscribed in the Java object Model... the complicated thing being to understand and to analyse the application
architecture.
The

trade

layers

are

also

more

efficient

72
http://www.supinfo.com

and

simpler

to

write.

Chapter 2. JSF Web framework


Objectives of this chapter :

Know when to use JSF

Understand its architecture

Display web pages

Validate forms

Realize that a web application can be very close from a Swing application.

1. Course
1.1. Introduction
1.1.1. Servlet / JSP limitations
The first step to create a Web Site in Java is to use Servlet and JSP. Even if its possible to create a Site with
only these technologies its clear that Servlet better suit for treatment and JSP for visual.
But Servlet/JSP has some limitations:

Create its own tags is difficult

There are no highlevel tags


Its hard to process user inputs
Its hard for a beginner to create a Site with a clean architecture. There are no guides to help you.

1.1.2. Java Server Faces presentation


Java Server Faces (JSF) is a Web Framework. It provides highlevel components to quickly create complex Web
Site. It also helps to manage all commons tasks like data validation, navigation management.
JSF is based on the model MVC (ModelViewControler) and provides a notion of Web components similar to
Swing. Web components can holds listeners (clic on a button, clic on a link, ) on server side.
JSF uses a HTML/Object mapping, it means that a HTML component will be mapped to a JSF component. This
mapping is done on the server side. This mapping allows us to create a site in Java or to use HTML/JSFP/JSF
tags. Of course you can mix the two techniques.
When a user visits a page, JSF components will be transformed into HTML and viceversa. This transformation
is done thanks to the HTML/Object mapping.
Finally JSF manage all navigations rules into a unique file named "navigation file". This helps to see how
73
Created by XMLmind

XSL-FO Converter.

navigation works for a Site at a glance..


JSF offers the following services:

Provides a HTML/Object mapping

Save the state of JSF components between requests

Transform JSF components into HTML


Manage events (click on a button, field modification, ) on server side

Instanciate and attach JavaBeans to the session, request or application automatically

Extensibility, numerous JSF components are available on the Internet. This goes from calendar to tree by
going through sortable table and progress bar

Support a plugin system which can be used to modify the way JSF works

Manage data conversion (can convert a String into a Date, a String into a business object and viceversa...)
Validate users requests (test field length, content type, )

Manage errors and exceptions and provides clear error messages

Manage navigation depending on interaction on a data model

Manage internationalization
1.1.2.1. JSF Audience
A large audience can use JSF. From application developer, to designer, everyone can use JSF. There are three
main categories of people between five.

Application architect which will create application, define navigation file, classes/libs to use to make the link
between view and services layers

Developers who implements all the Web Site

Page designers who will works with HTML/JSP/JSF tags


Last two categories of people which use JSF are:

People who want to extends JSF, to create custom components


74
Created by XMLmind

XSL-FO Converter.

IDE creators who will use JSF as the base of the IDE and extends JSF functionalities thanks to custom
components. For example Sun has created Java Studio Creator, an IDE dedicated to JSF and which JSF as its
core.

1.1.3. JSF Evolution


JSF is a specification proposed by the JCP (Java Community Process : www.jcp.org ). So there is not only
one implementation of JSF, but only a document which describes how JSF works.
Offical JSF specifications can be downloaded at :

http://jcp.org/en/jsr/detail?id=127 for JSF 1.0 et http://jcp.org/en/jsr/detail?id=252 for JSF 1.2.


Sun provides a reference implementation for each version. Apache provides its own one named "MyFaces"
(currently only for JSF 1.1).
JSF version 1.0 and 1.1 were not part of J2EE. Its only since JEE 5 that JSF 1.2 has become a standard.
JSF 1.2 is based on the following librairies:

JSF version 2.1

Servlet 2.5

JSE 5.0

JEE 5.0

JavaBeans 1.0.1

JSTL 1.2
All JEE 5 application servers supports JSF 1.2. If you dont have a JEE 5 server, you can still use JSF 1.1 with a
Servlet/JSP 2.3/1.2 server or JSF 1.2 with a Servlet/JSP 2.5/2.1 server. In a global manner, to run JSF 1.2 with a
non JEE 5 server, you have to include all JSF librairies into your wars. However there may be unexpected
behaviors depending on your application server. Check the documentation of your server before deploying a JSF
application.
This lesson has been created for JSF 1.1 and 1.2. Elements specific to JSF 1.2 are specified.

1.1.4. Difference with Struts


Struts and JSF can look the same. There has been created to go beyond the limits of Servlet/JSP. They provide:

Managed Beans, it means that their lifecycle are managed by the container

Form validation

Navigation defined in only one file


JSF also support events and independence of HTML rendering. JSF pages can be used to generate XML, SVG,
75
Created by XMLmind

XSL-FO Converter.

...
But they also have a different way of working. Struts use an actionresponse model. Each user request to Struts
pages must go through a mini Servlet (action class) that can do some process and define the JSP target page.
With JSF a request is directly targeted to a JSP/JSF page. Then the page can use JavaBeans to define what
process to execute. This model promotes code reuse thanks to components.
Finally JSF is a JEE 5 standard which ensure that community and majors actors (Oracle with ADF/MyFaces,
Sun with Java Studio Creator 2, ) will maintain it.

1.2. JSF architecture


JSF is like Swing but for Web. JSF use components to represent structure of a page. Components provide
methods to manage listeners, validate user input and data conversion. All components exist as Java classes, so
you can use them inside Java code. But in practice all components are manipulated through JSF tags.
By default JSF use HTML/JSP/JSF tags but in the chapter "9 Facelets" well see that we can use another tag
libs.
JSF components provides:

JavaBeans interaction. JavaBeans represents the model and are used to interact with lower layers of your
application

Rendering system used to translate JSP/JSF tags to HTML

Obersvator/Observer system

Conversion model

Validation model
All these services are manipulated through JSF tags, which is easier than in Java code.

In practice components are mostly invisible, its like a JavaBean is directly linked to JSF tags.
In MVC model, JSF components are the view, JavaBeans represents model. Controller is the Faces Servlet.

76
Created by XMLmind

XSL-FO Converter.

And JSF use a file which summarize:

all navigation rules

declaration of managed beans.


With the navigation file you can see how user request are processed. You can even do conditional navigation.
JavaBeans that are declared in the configuration file are named "managed bean". The container instantiate beans
when a page need it.

1.2.1. JSF integration inside a JEE architecture


To reuse the architecture schema from the JEE lesson, JSF correspond to Application and Client layers. Its
possible to interact with EJBs or any other type of service layer. JavaBeans provide access to Service layer.
Heres an example of an application with EJB + JSF:

In a small application, its also possible to directly interact with a database from JavaBeans.
Heres an example of a site architecture:

1.2.1.1. LifeCycle
Well now see how server process a JSF request. JSF is made of a single Servlet. This Servlet is used to
transform JSF tags into components that are manipulated on the server side. And it also produces HTML from
JSF tags. When a client send a HTTP request to a server. The Servlet first retrieve the component tree which
maps to a requested JSF page by looking to identifiant put inside of the HTML code.
JSF Servlet can be executed in a Servlet or Portlet container. Class which manages lifecycle is
"javax.faces.context.FacesContext". When a request arrive on the server, a new instance of FacesContext is
created and process the request.
Lets see in details how request processing works:

77
Created by XMLmind

XSL-FO Converter.

1.2.1.1.1. Restore View


When a request arrive on the server. It transmit it to the JSF Servlet. Then JSF Servlet create component tree
which maps to the JSF page. Once all JSF components are instantiated, this phase is over.
1.2.1.1.2. Apply Request Values
If parameters has been passed with the request, Servlet set all news values to corresponding component. For
example if an user send an form, values of textfields are set to components which reprensent these text fields.
Some components can trigger an event once its value change. These events are processed during the "Invoke
Application" phase or immediately if the "immediate" attribute is set to true.
Event processing will be review in details in the chapter: " Behaviors ".
1.2.1.1.3. Process Validations
Components that accept user entry can define validation rules. Servlet process these rules during this phase.
The property "immediate" can be used to force processing of validation rules during the phase "Apply Request
Values".
1.2.1.1.4. Update Model Values
From now, all update values has been done on components. The model (JavaBeans) which are mapped to
components will now be updated to reflect these new values.
1.2.1.1.5. Invoke Application
During this phase, all events are processed. This include events triggered during "Apply Request Values" phase.
Finally the navigation is resolved, this means that destination page is determined.
1.2.1.1.6. Render Response
In this last phase, JSF page is translated to HTML.

1.3. Develop with JSF


What are the steps to develop a JSF application? Well now see with a "Hello World" what are the minimal
78
Created by XMLmind

XSL-FO Converter.

steps to create a JSF site.

Install JSF

Activate JSF in "web.xml" file

Create JSF pages

Create JavaBeans (optional)

Configure application with "faces-config.xml" file (optional)

1.3.1. JSF installation


If you want to use JSF 1.2, the simplest thing is to use a JEE 5 server. In this case, JSF support is integrated.
You can download GlassFish at: https://glassfish.dev.java.net/ .
To use JSF 1.1 or JSF 1.2 on a server that dont support JSF, you have to download an implementation. You can
download Sun implementation at: http://java.sun.com/javaee/javaserverfaces/download.html
In the "lib" folder of the zip file, there are all jars necessaries to develop a JSF application. These jars must be
placed under "WEB-INF/ lib" of Web archive (War).
Jars necessaries to JSF 1.1 are:

" jsfapi. jar ", contains JSF classes definition (package javax.faces)

" jsfimpl. jar ", contains implementation of JSF classes

" jstl.jar ", allow usage of JSTL tags. These tags are referenced by JSF implementation

" standard.jar ", allow usage of standard tags. These tags are referenced by JSF implementation

" commonsbeanutils. jar ", utility classes to manipulate JavaBeans

" commonsdigester .jar ", to manipulate XML

" commonscollections. jar ", extension to Collections framework

" commonslogging. jar ", to create logs


For JSF 1.2, necessaries jars are:

" jsfapi. jar ", contains JSF classes definition (package javax.faces)

79
Created by XMLmind

XSL-FO Converter.

" jsfimpl. jar ", contains implementation of JSF classes

1.3.2. Enable JSF


First activate JSF in "web.xml". You have to create a redirect user requests to JSF Servlet. In this example, well
redirect all requests which begins with "/faces/" to JSF Servlet.
[CODE:xml]<?xml version='1.0' encoding='UTF8'?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application
2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Application name</display-name>
<!--Faces Servlet -->
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<!--Mapping-->
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
</web-app>

For JSF 1.2, header of the file is:


[CODE:xml]<?xml version='1.0' encoding='UTF8'?>
<web-app
version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchemainstance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/webapp_2_5.xsd">

JSF pages must have ".jsp" extension. Its a JSF parameter that you can modify, see chapter "6.3 Context
parameters".
An url like "/faces/index.jsp" is used to access JSF pages. If you try to access directly the jsp page (/index.jsp),
the request will not go through JSF Servlet and all JSF tags will not be processed.
Heres another example of mapping. To acess a page you have to type its URL but replace its extension with
".jsf".
[CODE:xml]<web-app>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
</web-app>

Although you access page by using a ".jsf" extension. All pages need to have the ".jsp" extension when you
create it. When client ask for "index.jsf" page, JSF Servlet look for "index.jsp" on the server and process it like a
JSF page.

1.3.3. Hello World


Now that JSF is activated we can write our first. Heres a basic page:
[CODE:xhtml]<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<html>
<head>
<title>First JSF page</title>

80
Created by XMLmind

XSL-FO Converter.

</head>
<body>
<f:view>
Hello World
</f:view>
</body>
</html>

The first 2 lines declare JSF taglibs. The following is a classic HTML structure. The only difference is the
[CODE:xhtml]<f:view>...</f:view>

tag. Its the root tag for all others JSF tags.
In this example, we can see we can display text directly on the page. However it exists dedicated tags for output,
especially for internationalization.
1.3.3.1. War Structure
Once the JSF pages are created, there must be packaged into a War (Web Archive). A War must have the
following structure:

Table 2.1.
WEB-INF/classes

Contains java classes (like JavaBeans)

WEB-INF/lib

All libraries (jars) of the project.

WEB-INF/faces-config.xml

Configuratin file(optional)

WEB-INF/web.xml
*.jsp

All jsp pages

For example in JSF 1.1, we have:

1.3.4. Deployment
Even if your server supports JSF, you can package your own JSF jar because its always the jar of the server
which have priority.
If you want to add support of JSF on a server, you can copy all the JSF jars in the libraries folder of the server.
For example in Tomcat, you can put them in the folder "TOMCAT_HOME/shared/ lib". This folder is specific
to the server, so you have to check the server documentation to find the good folder.
1.3.4.1. JBoss
JBoss supports JSF 1.1 since its version 4.0.3. This support is based on the implementation of Apache :
MyFaces. If you want to use the Sun implementation, you have to delete the MyFaces jars on JBoss. They are
on the folder:
JBOSS_HOME/server/default/deploy/jboss-web-tomcat55.sar/jsf-lib
If "default" is the configuration that you use.
81
Created by XMLmind

XSL-FO Converter.

Then, you have to package the Sun jars of JSF 1.1 into your War.
Support of JSF 1.2 is planned for JBoss 5.
1.3.4.2. Example
Well now see a little web site made in JSF. The goal is to show how look JSF tags and code. The web site uses
validation and errors displaying, site navigation mechanisms.
There are only 2 pages. The first display a form used to register. When the user submit it, data of the form are
displayed in a second page.
If theyre validation errors (missing field, too short password, ) messages are displayed directly on the form.
Lets start with the form page, "Register.jsp":
[CODE:xhtml]<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<html>
<head>
<title>Register</title>
</head>
<body>
<f:view>
<h1>Register</h1>
<h:form>
<!--Text field for the last name-->
<h:inputText id="lastName" required="true" size="21" maxlength="20" value="#{user.lastName}">
<!--Label of this text field -->
<h:outputLabel for="lastName" value="Last name: "/>
<!-- Validator: the name length must be betwenn 3 and 20 -->
<f:validateLength minimum="3" maximum="20"/>
</h:inputText>
<!-- Display errors message about the field 'lastName' -->
<h:message for="lastName" style="color: red"/>
<br/>
<!--Text field for the first name -->
<h:inputText id="firstName" required="true" size="21" maxlength="20" value="#{user.firstName}">
<h:outputLabel for="firstName" value="First name: "/>
<f:validateLength minimum="3" maximum="20"/>
</h:inputText>
<h:message for="firstName" style="color: red"/>
<br/>
<!-- Text field for the password -->
<h:inputSecret id="password" required="true" size="21" maxlength="20" value="#{user.password}">
<h:outputLabel for="password" value="Password: "/>
<f:validateLength minimum="3" maximum="20"/>
</h:inputSecret>
<h:message for="password" style="color: red"/>
<br/>
<h:commandButton value="Submit" action="success"/>
</h:form>
</f:view>
</body>
</html>

Syntax "#{user.lastName}" allows to use a JavaBean. Here "user" is the name of a bean and "lastName" is the
name of one of its properties.
Now well look at the bean class:
[CODE:java]package com.labosun;
public class User {
private String lastName;
private String firstName;
private String password;
public String getLastName() {
return lastName;
}

82
Created by XMLmind

XSL-FO Converter.

public String getPassword() {


return password;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public void setLastName(String lastName) {
this. lastName = lastName;
}
public void setPassword(String password) {
this. password = password;
}
}

Now lets see the configuration file of JSF (faces-config.xml). This file gives a name to the previous bean.
[CODE:xml]<managed-bean>
<!-- Name of the bean inside JSF page -->
<managed-bean-name>user</managed-bean-name>
<!-- Bean Class -->
<managed-bean-class>com.labosun.User</managed-bean-class>
<!-- Bean scope -->
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>

Finally well look at the Confirmation page. This page display the lastname and the firstname of the user.
Confirmation.jsp :
[CODE:xhtml]<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<html>
<head>
<title>Registration</title>
</head>
<body>
<f:view>
<h1>Successful registration </h1>
Welcome <h:outputText value="#{user.firstName} #{user.lastName}" />
</f:view>
</body>
</html>

As you can see, syntax "#{user.prenom}" is used again here to reference the bean.
The last step for this demo is to define a navigation rule, so when the user click and the submit button, he goes
to the confirmation page. For recall, the code for the submit button is:
[CODE:xhtml]<h:commandButton value="Submit" action="success"/>

"Action" attribute define a string which will be linked to the confirmation page..
[CODE:xml]<navigation-rule>
<!--Start page -->
<from-view-id>/Register.jsp</from-view-id>
<navigation-case>
<!-- String used by the start page -->
<from-outcome>success</from-outcome>
<!--Destination page-->
<to-view-id>/Confirmation.jsp</to-view-id>
</navigation-case>
</navigation-rule>

Now well see the result:

83
Created by XMLmind

XSL-FO Converter.

Site design is not good, but well see later how to do it better.
When the user submit the form, the confirmation page is displayed:

If the form is not valid, the following messages are displayed:

You can customize these messages as explained in the chapter "8.2.1 Customize messages".

1.4. Basic elements


Root class of all components in JSF is "javax.faces.component.UIComponent". This class definie attributes
shared by all JSF components. This components are not specifics to HTML, but provide similar functionalities:
links, table, form, buttons, combo box, list, ... HTML specific components subclass a standard component. They
are in the package "javax.faces.component.html".
In practice, youll use JSF tags to use components and the attributes of the tag to call the properties or methods
of this component.
For example, the UIComponent class define a property "id". This property is accessible directly from a JSF tag
with an attribute of the same name.
[CODE:java]public class UIComponent {
private int id;
public int getId() {...}
public void setId() {...}
}

And for any JSF tag, you can write:


[CODE:xhtml]<h:baliseJSF id="identifiant " />

Be careful:
JSF tags cant use some properties.
There are some tags attributes that dont map to component property or method.

1.4.1. Behaviors
There are 5 interfaces that can define a behavior to components.

Table 2.2.
84
Created by XMLmind

XSL-FO Converter.

Interface

Description

StateHolder

For component that maintain a state between user


requests. UIComponent implements this interface. So
all JSF implements it.

NamingContainer

Indicates that all children components must have a


unique Id. Its not mandatory to set an Id (server will
automatically define one), but if you define one, it
must be unique.

ValueHolder

The component has a value. This value can be linked


to a JavaBean. The value can be converted in a specific
type, see chapter "7.3 Data conversion".

EditableValueHolder

Extend ValueHolder. The value of the component can


be edited and when it happens, a event is fired on the
server side. And you can defini validation rules for
editing.

ActionSource

State that this component will fire an event when the


user activates it. Example : a HTML link fire an event,
when a user click on it.

Note: In JSF 1.2, interface " ActionSource " has been subclassed into " ActionSource2 ".
JSF tags which implements ValueHolder has a "converter" attribute. Its used to define how the value must be
converted to another type. For example, you can convert the String "10/05/06" into a Date object directly.
JSF components which implements EditableValueHolder has the following attributes:

"validator", define the method of a bean that will validate the used entry.

"valueChangeListener", define the method that will be called when the value of the component change.
JSF components which implements ActionSource has the attribute "actionListener ". It define the method that
will be called when the user activate this component.
Behaviors are detailed in chapter "Behaviors".

1.4.2. Generics behaviors


JSF is independent from HTML. Thats why there is generic rendering system for tags and different
implementations for every language. But in practice there is only the HTML implementatio.
So they are 2 categories of components, the first for generic JSF and the second one for HTML.
The following table sum up all generic components. Theyre all from the package "javax.faces.component".

Table 2.3.
Class (implemented interfaces)

Description

UICommand (ActionSource)

Root class for all components that can fire an event.

UIData (NamingContainer)

Used to manipulates data from a Collection , an array


or a ResulSet.

UIForm (NamingContainer)

Represents a form.

UIGraphic

Used to display pictures.

UIInput (extends UIOutput) (EditableValueHolder)

Used to enter data.

UIMessage et UIMessages

Used to display messages. See chapter "8.2 Messages


management".

85
Created by XMLmind

XSL-FO Converter.

Class (implemented interfaces)

Description

UIOutput (ValueHolder)

Used to display text.

UIPanel

Group JSF components into a single one.

UISelectBoolean
(EditableValueHolder)
UISelectMany
(EditableValueHolder)

(extends
(extends

UIInput) Used to manipulate a Boolean value.


UIInput) Used to select multiples values from a list.

UISelectOne (extends UIInput) (EditableValueHolder) Used to select a single value from a list.
All these components have the following attributes.
1.4.2.1. Attribute id
This attribute defines an identifier for component. Its not mandatory to use an id. Its useful to reference
components on a page. A indentifier must respect the following rules:

It must begins with a letter (see method String.Character.isLetter()) or the character '_'.

Others characters can be letters, digits (see method Character.isDigit()),'' or '_'.


Example:
[CODE:xhtml]<h:JSFtag id="identifier" />

Note: To optimize JSF performance, its recommended to use short id.


1.4.2.2. Renderer attribute
Its a boolean that define if the components is displayed or not
Example:
[CODE:xhtml]<h:JSFtag renderer="false" />

This attribute can be used to display a message only if a search has returned no results.
1.4.2.3. Immediate attribute
As seen in chapter " LifeCycle", this attribute affect the lifecycle.

1.4.3. HTML components


HTML components are located in the package "javax.faces.component.html". See chapter "5 JSF Taglib" for a
complete list This chapter only covers commons attributes of these components.
You can use previous attributes and the following attributes:
1.4.3.1. CSS style
This attribute define the CSS code of the tag. Heres an example with the tag <h:outputText /> that display a
text.
[CODE:xhtml]<h:outputText style="font-size: 150%; color: red" value="Hello"/>

Thats translated in the following HTML :


[CODE:xhtml]<span style="font-size: 150%; color: red">Hello</span>

1.4.3.2. CSS class

86
Created by XMLmind

XSL-FO Converter.

It defines the CSS class of a tag.


Example:
[CODE:xhtml]<h:baliseJSF styleClass="title1" />

1.4.3.3. escape
Only some components have this attribute. If set to true, characters '<', '>' and '&' are converted into HTML
code.
1.4.3.4. JavaScript events
All tags that represents a HTML tags, also share the same javascript attributes. Heres a list of javascript
attributes:
" onclick, ondblclick, onblur, onchange, onclick, ondblclick, onfocus, onkeydown, onkeypress, onkeyup,
onmousedown, onmousemove, onmouseout, onmouseover, onmouseup, onreset, onselect, et onsubmit ".
1.4.3.5. Linking between JSF Components and JavaBeans
JavaBeans represents the model part into the MVC model. This model clearly separate different layer of an
application. They are to way to bind a component to a JavaBean:

Only the value of the component is bind to a JavaBean property (only for component that has a value).

The component itself is bind to a JavaBean property.


The syntax to use JavaBean in JSF tags is EL (Expression Language). It web specific language. Since JSF 1.2
its been unified with JSP language under the name Unified Expression Language.
This lesson only cover JSF aspects of this syntax. The next chapter "4.5 Unified Expression language" details all
JSF features of this syntax.
An EL expression start with "#{" and end with "}".This syntax use an object oriented notation. You can used
any variable of a page just by using its name. From this variable you can use any property or method.
Example:
#{javaBean.method}
#{javaBean.property}

1.4.3.5.1. Value
To bind the value of a component to a bean property, you have to use the attribute "value" and specify the
referenced bean with EL syntax.
Example:
[CODE:xhtml]<h:JSFTag value="#{javaBean.property}" />

There are restrictions on the type that you can bind:

Table 2.4.
Component

Possible values

UIInput, UIOutput, UISelectItem, UISelectOne

A primitive, a String, a Number or any class that have


a converter. See chapter "7.3 Data conversion" for
more information.

UIData

JavaBean array or list, Simple JavaBean,


java.sql.ResultSet, javax.servlet.jsp.jstl.sql.Result or
javax.sql.RowSet.
87
Created by XMLmind

XSL-FO Converter.

Component

Possible values

UISelectBoolean

boolean or Boolean

UISelectItems

String, Collection, Tableau or Map

UISelectMany

Array or List.

Restrictions will be detailed in following chapters.


1.4.3.5.2. Instance
If you want to bind a component instance to a bean property. The property must be of the same type that the JSF
component.
For example, if you want to bind the component HtmlOutputText to a JavaBean. You first declare the following
property:
[CODE:java]public class LinkedBean {
private HtmlOutputText composant;
public HtmlOutputText getComposant() {
return this.composant;
}
public void setComposant(HtmlOutputText c) {
this.composant = c;
}
}

And then, you just specify the bean property with the attribute "binding":
[CODE:xhtml]<h:outputText binding="#{linkedBean.composant}" />

Difference between attributes "value" and "binding" is that "value" only bind the value of component and
"binding" bind the component instance. For example a text field accept a "String", a "Number" or a primitive as
value. So attribute "value" must have the same type. A text field is represented by the class "HtmlInputText".
The class hierarchy is:

Attribute "binding" can be any of these types.


1.4.3.6. Unified Expression language
Unified EL (Unified Expression Language) is language created to propose a simple way to access Java code
from tags. This syntax has appeared with JSP 2.0 and JSF 1.0 under the name Expression Language. JSP and
JSF used 2 differeents versions of EL. Its only in JSP 2.1 and JSF 1.2 that the language has been unified under
the name "Unified Expression Language". By default Servlet version 2.3 and previous ignore this syntax. Its
possible to change this behavior with the directive:
[CODE:xhtml]<%@ page isELIgnored ="true|false" %>

In JSP, a EL expression is like "${ }". In JSF we use "#{}". Without explain differences between these 2
syntaxes, remember that its generally bad to mix JSF and JSP EL expressions (like mixing AWT and Swing).
The best way is to use only JSF syntax and replace JSP tags by their equivalents in Facelets tags (see chapter "9
Facelets").

88
Created by XMLmind

XSL-FO Converter.

1.4.3.6.1. Variables
Its possible to reference any object in a page. For example:
#{person}

The Web (or Portlet) container will look for an object which is named "person" in the page, the request, the
session or the application. "." Operator is used to access a property, method of an bean. For example to access
"name" property of "person", youll write:
#{person.name}

To access method "checkLogin" of "person":


#{person.checkLogin}

To access an array or a list, use operator "[]". Example, you want to get the third element of an array:
#{uelBean.tab[2]}

In this case expression "#{bean[property]}" is equivalent to "tab.get(index)". If exception


IndexOutOfBoundsException is thrown, null is returned. For others exceptions, an error is returned. For Map,
use expression "#{bean['key]}" is equivalent to "bean.get(key)" or null if the Map doesnt contains the key. For
example, if you want to get the value mapped to the key "login":
#{uelBean.map['login']}

Operator "[]" can also be used to access property or method. In this case, the name of the property (or method)
must be enclosed with quote.
Examples: Access to property "name" of "person".
#{person['name']}

Which is equivalent to:


#{person.name}

Call to method "checkLogin" of "person".


#{person['checkLogin']}

Which is equivalent to:


#{person.checkLogin}

1.4.3.6.2. Implicit objects


They are implicits objects in JSF pages. They are always accessible with EL expression.

Table 2.5.
Object name

Description

applicationScope

A Map which map application attributes to their


values.

cookie

A Map which map cookie values to a their values.

facesContext

Current FacesContext instance

header

A Map which HTTP headers to their values.

headerValues

A Map which HTTP headers to String array. An array


contains all values of a header.

initParam

A Map which map init parameters to their values.

param

A Map which map request parameters to their values.

paramValues

A Map which map request parameters to their values.


An array contains all values of a parameter.
89
Created by XMLmind

XSL-FO Converter.

Object name

Description

requestScope

A Map which map request attributes to their values.

sessionScope

A Map which map session attributes to their values.

view

Root component of a JSF page.

1.4.3.6.3. Operators
Most of Java operators can be used. But you can also used

Arithmetic: +, -, *, /,%, "div" and "mod".

Logical: &&, ||, !, "and", "or" and "not".

Relational: ==, "eq", !=, "ne", <, "lt", >, "gt", <=, "le", >=, "ge". These operators can compare primitives and
String.

Compound: expression ? val1 : val 2.

instanceof

"empty" test if a value is null or if an array or a list is empty.

1.5. JSF Taglibs


Now we will study some useful tag in a JSF page. Every JSF component (not HTML) is a tag which is prefixed
by default with a "f". The tags name is the same as the component without the "UI" prefix. Every HTML
component is a tag which is prefixed by a "h" by default. The tags name is the same as the component without
the "Html" prefix.

1.5.1. JSF View


The first tag that we have to use in JSF is <f:view>, this tag permit to declare the view which will contains the
others tags.
[CODE:xhtml]<f:view>
<!--JSF tags -->
</f:view>

1.5.2. Simple text


The <f:verbatim> tag generate an UIOutput component from its content. Its the simpler tag to display text, but
its not a specific HTML tag. So its not possible to use every HTML attributes like the CSS style.
Example:
[CODE:xhtml]<p> <f:verbatim>Hello Verbatim</f:verbatim> </p>

This example will generate this HTML code:


[CODE:xhtml]<p>Hello Verbatim</p>

1.5.3. Output components


The tags which permit to display some text are:

90
Created by XMLmind

XSL-FO Converter.

<h:outputText>

<h:outputFormat>

<h:outputLabel>
They correspond to the components:

HtmlOutputText

HtmlOutputFormat

HtmlOutputLabel
They inherit from UIOutput which implement ValueHolder.The "value" attribute permit to define the text to
display. This attribute can be associated with a primitive, a String, a Number or every class which contains a
data converter (Chapter "7.3 Conversions").
1.5.3.1. Simple text
The simpler tag to display a text in one line is:
[CODE:xhtml]<p> <h:outputText value="text"/> </p>

This tag will generate this HTML code:


[CODE:xhtml]<p>text</p>

Here is an other example but this time we will include some text in the tag.
[CODE:xhtml]<p> <h:outputText value="Another test of " style="color: red">
outputText
</h:outputText> </p>

This example will generate this HTML code:


[CODE:xhtml]<p>outputText <span style="color: red">Another test of </span></p>

Graphically youll have:

Note that the text in the tag is displayed before the text specify in the "value" attribute. Only the text write in the
tag can us CSS style.
Note : Its possible to display a text from a resource file (Chapter "8.1 Internationalization).
1.5.3.2. Formatted output
The <h:outputFormat> tag displays a formatted message with the format() method from the MessageFormat
class. Its possible to transmit parameters on using under tag <f:param />.
Example of JSF code :
[CODE:xhtml]<p> <h:outputFormat value="outputFormat is {0}"><br />
<f:param value="great" /> <!--Parameters-->
</h:outputFormat> </p>

This example generate this HTML code:


91
Created by XMLmind

XSL-FO Converter.

[CODE:xhtml]<p>outputFormat is great</p>

Other use:
[CODE:xhtml]<h:outputFormat
value="Precision at 2 digit: {0,number,#.##}, at 1 digit: {0,number,#.#}">
<f:param value="#{basic.nb}" />
</h:outputFormat>

This example will display:


Precision at 2 digits: 4,15, at 1 digit: 4,2

For more information, look at the MessageFormat class documentation.


1.5.3.3. Label
The <h:outputLabel> tag represent the <label> tag on HTML. It permts to affect a label to a input component
like text field or a checkbox. This tag is used like an under tag of the referenced tag. The "for" attribute contains
the id of the right label.
Example :
[CODE:xhtml]<h:inputText id="address " value="your address here"> <!text field >
<h:outputLabel for="address " value="Address:" />
</h:inputText>

This example will generate this HTML code:


[CODE:xhtml]<label for="address">Address:</label>
<input id="address" type="text" name="address" value="your address here" />

You can also use the <h:outputLabel> tag. Example :


[CODE:xhtml]<h:outputLabel for="city" value="City:" />
<h:inputText id="city" value="Strasbourg" />

Here is what it will display with the 2 examples :

1.5.4. Form
This tag represents a form. The component implements "NamingContainer". It means that every tags in a form
must have an unique id.
Example:
[CODE:xhtml]<h:form>
</h:form>

JSF will add some information when the tag will be translated into HTML. The method used by the form is
always "POST" and the encoding in " application/x-www-form-urlencoded".
[CODE:xhtml]<form id="_id0" method="post" action="/HW/04Form.jsf" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="_id0" value="_id0" />
</form>

A last example which illustrate how to add an id for every under tags of a form:
[CODE:xhtml]<h:form>
<h:outputText id="name" value="text" />
</h:form>

In HTML:
[CODE:xhtml]<form i d="_id1" method="post" action="/HW/04Form.jsf" enctype="application/x-www-form-urlencoded">
<span id="_id1:name">text</span>

92
Created by XMLmind

XSL-FO Converter.

<input type="hidden" name="_id1" value="_id1" />


</form>

Every component which doesnt have an id will have an attributed one. The id used is prefixed by the id of the
form. It permits to give few times the same id in different form.

1.5.5. Input components


The components to type data:

HtmlInputText

HtmlInputTextarea

HtmlInputSecret

HtmlInputHidden
They inherit of UIInput which implements EditableValueHolder. The "value" attribute of these tag permit to
affect a value by default to a field. The value can be linked to a primitive, a String, a Number or every class
which have a data converter. Its possible to use "required" attribute to indicate that a field is obligatory.
1.5.5.1. Text field
The simpler tag to type text is <h:inputText>.
[CODE:xhtml]<h:inputText maxlength="20" size="20" value="default value"/>

This example will generate this HTML code:


[CODE:xhtml]<input type="text" value="default value" maxlength="20" size="20" />

1.5.5.2. Multi lines text field


The <h:inputTextArea> tag permit to type a text in few lines.
[CODE:xhtml]<h:inputTextarea cols="10" rows="10" />

This example generate this HTML code:


[CODE:xhtml]<textarea cols="10" rows="10"></textarea>

1.5.5.3. Password field


The <h:inputSecret> permit to type a password. The "redisplay" attribute permit to keep it when the page is
reloaded. (By default its value is false).
[CODE:xhtml]<h:inputSecret redisplay="false" value="#{bean.password}" />

The JSF code generate this HTML code:


[CODE:xhtml]<input type="password" />

1.5.5.4. Hidden field


The <h:inputHidden> tag permit to include a hided field in a web page.
[CODE:xhtml]<h:inputHidden value="#{bean.hide}"/>

This JSF code generate this HTML code:


[CODE:xhtml]<input type="hidden" value="value" />

93
Created by XMLmind

XSL-FO Converter.

1.5.6. Link
It exist 2 kind of link in JSF:
The simple links, which dont start any event on the server side.

The link which will start an event on the server side. It will permit to manage the navigation of the web site
with a unique file.
Every links of your web site (which are linked to your web site) have to be the second type. With this kink of
link youll be able to define the navigation of your web site in a configuration file.
1.5.6.1. Simple link
The <h:outputLink> tag permit to display a link. It uses the "HtmlOutputLink" component which inherits of
UIOutput which implements ValueHolder.
The "value" attribute permit to define the url of the link. The value can be associated to a primitive, a String, a
Number or every class which have a data converter. It doesnt exist attribute which define the text of the link.
To define the text, we have to use an under tag like <h:outputText>.
Example :
[CODE:xhtml]<h:outputLink value="url ">
<h:outputText value="Text of the link" />
</h:outputLink>

We can use few under tags to define the text:


[CODE:xhtml]<h:outputLink value="url ">
<h:outputText value="Text " />
<h:outputText value="of the " />
<h:outputText value="link" />
</h:outputLink>

In the 2 cases, the HTML code will be:


[CODE:xhtml]<a href="url">Text of the link</a>

Every urls are relatives to the current url. Its possible to refer to the web site root on prefixing the url by "/".
If we have the following url:
http://localhost:8080/JSFCours/faces/testLiens.jsp

Where " JSFCours " is the web site context and " faces " is JSF file mapping. So, for example :

" index.jsp " is reachable through the url " http://localhost: 8080/JSFCours/faces/index.jsp "

" /index.jsp " is reachable through the url " http://localhost:8080/index.jsp "
It is possible to retrieve the web site context and mapping with the following expressions:

#{facesContext.externalContext.requestContextPath}, web site context

#{facesContext.externalContext.requestServletPath}, mapping to the JSF Servlet. This string is empty if


mapping use a suffixe (like *.jsf).

94
Created by XMLmind

XSL-FO Converter.

#{facesContext.externalContext.requestPathInfo}, path to the current web page, starting from the JSF Servlet.
For example, if you have the URL " http://localhost:8080/JSFCourse/faces/testLiens.jsp " so you will retrieve
the following values:

facesContext.externalContext.requestContextPath = /JSFCourse

facesContext.externalContext.requestServletPath = /faces

facesContext.externalContext.requestPathInfo = /testLiens.jsp
1.5.6.2. JSF link
You can create a link with " HtmlCommandLink ". It extends UICommand which implement " ActionSource ".
The tag related to this component is <h:commandLink>. This tag has to be nested inside a <h:form> tag.
Its " value " attribute allows to define its text (not destionation URL). The value can either be a primitive, a
String, a Number or any other class with a converter (see chapter about converters). This kind of link does not
use any URL to define destionation, but a string value. This one is evaluated inside JSF navigation rules which
are defined inside its configuration (see faces-config.xml file). See chapiter " 6.2 Navigation " for further
information about the action attribute and navigation rules.
Exemple :
[CODE:xhtml]<h:form>
<h:commandLink action="success" value="This is a JSF link" />
</h:form>

If no action attribute is defined, the link refreshes the current page.


It is also possible to nest a <h:outputText> tag to define the displayed text:
[CODE:xhtml]<h:form>
<h:commandLink action="success">
<h:outputText value="This is a JSF link" />
</h:commandLink>
</h:form>

The two previous example render the following HTML code:


[CODE:xhtml]..
<form method="post" action="/HW/06Liens.jsf" enctype="application/x-www-form-urlencoded">
<a href="#">lien success</a>
</form>
...

1.5.6.3. Parameters
It is possible to define parameters inside a link by nesting <f:param> tags. It has two main attributes, which are "
value " and " name " :
[CODE:xhtml]<h:form>
<h:outputLink value="index.jsp">
<h:outputText value="index.jsp"/>
<f:param name="id" value="2"/>
<f:param name="sortBy" value="price"/>
</h:outputLink>
<br/>
<h:commandLink>
<f:param name="id" value="6"/>
<f:param name="sortBy" value="name"/>
</h:commandLink>

95
Created by XMLmind

XSL-FO Converter.

</h:form>

They can be retrieved with the expression " #{param.ParameterName} ". In this case, it is :
[CODE:xhtml]<h:outputText value="id=#{param.id}, sortBy=#{param.sortBy}" />

You can test wether the parameter has been defined with the expression: " #{!empty param.ParameterName} ".
It allows defining tags only if a parameter exists. Example:
[CODE:xhtml]<h:outputText value="(Only displayed if 'id' exists) id=#{param.id}"
rendered="#{!empty param.id}"/>

1.5.7. Button
The component which display a button is " HtmlCommandButton ". It extends UICommand which implements
ActionSource (and ActionSource2 for JSF 1.2). A button works almost like link. Example :
[CODE:xhtml]<h:form>
<h:commandButton action="action value" value="Send" />
</h:form>

Below is the returned HTML code:


[CODE:xhtml]<input type="submit" value="Send" />

1.5.8. Checkbox
There are 2 components which display checkboxes:

<h:selectBooleanCheckbox> only one checkbox

<h:selectManyCheckbox> many checkboxes.


1.5.8.1. BooleanCheckbox Component
The " value " attribute define wether the checkbox is displayed (or not). It can only be a boolean value.
Example:
[CODE:xhtml]<h:selectBooleanCheckbox id="choice" value="#{bean.property}"/>

Returned HTML code:


[CODE:xhtml]<input id="choix" type="checkbox" />

To display a text close to the checkbox, you have to nest a <h:outputLabel> tag.
Example:
[CODE:xhtml]<h:selectBooleanCheckbox id="choice" value="#{bean.property}">
<h:outputLabel for="choice" value="Married :" />
</h:selectBooleanCheckbox>

1.5.8.2. ManyCheckBox component


Most of the time, you want to display many checkboxes in the same time to propose many choices. You have to
use the <h:selectManyCheckbox> tag. It has a " layout " attribute which allow displaying value either:

Horizontal side with " lineDirection " value

Vertical side with " pageDirection " value.


Selected boxes can be saved inside a List or Array object. It is referenced by the "value" attribute. You can also
96
Created by XMLmind

XSL-FO Converter.

define inside which boxes are selected by default (you will see that later). In order to define which boxes have to
be displayed, you have either to:

nest <f:selectItem> tags

or nest a single <f:selectItems> tag which need a reference with items from the managed-bean.
1.5.8.2.1. SelectItem
The nested <f:selectItem> tag is a check box. Its attributes " itemValue " and " itemLabel " contain the value
and the displayed text. Example:
[CODE:xhtml]<h:selectManyCheckbox id="ville" layout="pageDirection"
value="#{bean.selectedCities">
<f:selectItem itemValue="StrasValue" itemLabel="Strasbourg" />
<f:selectItem itemValue="LyonValue" itemLabel="Lyon" />
<f:selectItem itemValue="ParisValue" itemLabel="Paris" />
</h:selectManyCheckbox>

It displays the following french cities:

Below is the ManagedBean code:


[CODE:java]public class Bean {
private List selectedCities = new ArrayList();
public List getSelectedCities() {
return selectedCities;
}
public void setSelectedCities(List selectedCities) {
this.selectedCities = selectedCities;
}
}

Here, items value is " java.lang.String ". " #{bean.selectedCities} " expression create a link with the selected
cities. Its contains the "itemValue" of all the selected boxes. For example, when the user sends a form with the "
Strasbourg " city selected, thus " selectedCities " will contain " StrasValue ". If the user selects 2 boxes, "
selectedCities " will contain " StrasValue " and " LyonValue ". It is important to take care about the type of your
objects on the ManagedBean side. Indeed, you can either use an array of String (String []) or a List to contains
selected cties, but you can not use an array of integer because values are strings. If you want to create items with
objects of your choice (like your own class City), you have to use a converter. Indeed, JSF need a String value.
1.5.8.2.2. SelectItems
You can also initialize your items directly from a ManagedBean containing an Array, a Map or a List. Lets take
the following class as ManagedBean:
[CODE:java]public class Bean {
private List selectedCities = new ArrayList();
private List allCities = new ArrayList();
public Bean() {
//add available cities
allCities.add(new SelectItem("StrasbourgValue", "Strasbourg :"));
allCities.add(new SelectItem("LyonValue", "Lyon :"));
//city selected by default
selectedCities.add("LyonValue");
}
public List getAllCities() {
return allCities;
}

97
Created by XMLmind

XSL-FO Converter.

public void setAllCities(List allCities) {


this.allCities = allCities;
}
public List getSelectedCities() {
return selectedCities;
}
public void setSelectedCities(List selectedCities) {
this.selectedCities = selectedCities;
}
}

Then you reference your ManagedBean inside a <f:selectItems> tag:


[CODE:xhtml]<h:selectManyCheckbox id="ville" value="#{bean.selectedCities}">
<f:selectItems value="#{bean.allCities}" />
</h:selectManyCheckbox>

You can also use an array to save your cities:


[CODE:java]SelectItem[] allCities ;

Finally, you can use a Map. In this case, the keys are the values, and values of the map are the displayed labels.
Example:
[CODE:java]Map allCityMap = new HashMap();
allCitiesMap.put("Strasbourg :", "StrasbourgValue ");
allCitiesMap.put("Lyon :", "LyonValue ");

1.5.8.2.3. How to gather items?


It is possible to create SelectItem groups, by using the <f:selectItems> tag. You have to put your items inside a
SelectItemGroup. Its constructor has the following parameters:

Group name

Description

Activation (false means disabled and true means enabled)

A SelectItem array
Once a SelectItemGroup instanciated, you can gather many groups and items inside a List as you can see on the
following example:
[CODE:java]// city list
List allCities = new ArrayList();
//french cities
SelectItem[] citiesFrance = new SelectItem[3];
citiesFrance[0] = new SelectItem("StrasValue", "Strasbourg");
citiesFrance[1] = new SelectItem("LyonValue", "Lyon :");
citiesFrance[2] = new SelectItem("ParisValue", "Paris :");
//create a group for French cities
SelectItemGroup franceGroup = new SelectItemGroup("France",
"French cities", false, citiesFrance);
//german cities
SelectItem[] germanyCities = new SelectItem[2];
germanyCities[0] = new SelectItem("KehlValue", "Kehl :");
germanyCities[1] = new SelectItem("BerlinValue", "Berlin :");
// create a group for german cities
SelectItemGroup germanyGroup = new SelectItemGroup("Allemagne", "German cities", false, germanyCities);

98
Created by XMLmind

XSL-FO Converter.

SelectItem london = new SelectItem("LondresValue", "Londres :");


allCities.add(franceGroup);
allCities.add(london);
allCities.add(germanyGroup);

It displays the following page:

1.5.9. RadioButton
The <h:selectOneRadio> tag allows defining a radio button list. It use the class " HtmlSelectOneRadio " which
implement " EditableValueHolder ". A list is constructed with nested <f:selectItem> tags or a single
<f:selectItems> tag (see chapter " 5.8.2 MultipleCheckbox component " for more information about these tags).
Notice that only one button can be selected at the same time. The radio button selected can either be stored as a
primitive, a String, a Number or any class having a converter.
Example:
[CODE:xhtml]<h:selectOneRadio layout="lineDirection" value="#{bean.color}>
<f:selectItem itemValue="red" itemLabel="red"/>
<f:selectItem itemValue="white" itemLabel="white"/>
<f:selectItem itemValue="yellow" itemLabel="yellow"/>
</h:selectOneRadio>

The property referenced by the " value " attribute should have the same type as the item value. Above, "
#{bean.color} " is a String because values are Strings.

1.5.10. List
There is 2 components to display a list:

<h:selectOneListbox> to display a list with only one item selected in the same time (it works the same way as
<h:selectOneRadio>).

<h:selectManyListbox> display a multiple choice list (it works the same way as <h:selectManyCheckBox>).
The " size " attribute allows you to define how many lines you want to display.
Example:
[CODE:xhtml]<h:selectManyListbox id="color" value="#{bean.colors}">
<f:selectItem itemValue="red" itemLabel=" Red:"/>
<f:selectItem itemValue="white" itemLabel=" White:"/>
<f:selectItem itemValue="yellow" itemLabel=" Yellow:"/>
</h:selectManyListbox>

Below is the result:


[CODE:xhtml]<select id="color" size="3">
<option value="rouge">Red:</option>
<option value="blanc">White:</option>
<option value="jaune">Yellow:</option>
</select>

99
Created by XMLmind

XSL-FO Converter.

1.5.11. Combo Box


A Combo box is created by the <h:selectOneMenu> tag. It is very similar as <h:selectOneRadio> tag (see
chapter " 5.9 RadioButton " for further information).
Example:
[CODE:xhtml]<h:selectOneMenu id="city" value="#{bean.selectedCities}">
<f:selectItems value="#{bean.allCities}" />
</h:selectOneMenu>

1.5.12. Pictures
The <h:graphicImage> tag allows to insert a picture. It has the following attributes:

" url ", the path to the picture

" alt ", a description of the picture


[CODE:xhtml]<h:graphicImage url="URL to the picture" alt="description"/>

You can also use pictures as links by nesting a <h:graphicImage> tag inside a link component:
[CODE:xhtml]<h:outputLink value="http://java.net">
<h:graphicImage value="javadotnet.jpg" />
<h:outputText value="java.net" />
</h:outputLink>

Below is the result:


[CODE:xhtml]<a href="http://java.net"><img src="java.jpg" alt="" />java.net</a>

1.5.13. Panel
The <h:panelGroup> tag allows gathering many JSF components in order to handle them as only one tag.
Indeed, some components can only have one nested tag.
Example:
[CODE:xhtml]<h:panelGroup>
<h:outputText value="first child" />
<f:verbatim><br /></f:verbatim>
<h:outputText value="second child" />
</h:panelGroup>

It returns the following HTML code:


[CODE:xhtml]first child<br />second child

Notice the <f:verbatim> tag around <br/>. It allows returning the text and tags in the same postition. Indeed, if
you do not use it...:
[CODE:xhtml]<h:panelGroup>
<h:outputText value="first child" />
<br />
<h:outputText value="second child" />
</h:panelGroup>

You could have the following result:


[CODE:xhtml]<br />first childsecond child

1.5.14. Table
There is two ways to create tables with JSF:
100
Created by XMLmind

XSL-FO Converter.

<h:panelGrid>

<h:dataTable>
They both have the following attributes:
footerClass: define which CSS class(es) are used to display the tables footer
headerClass: define which CSS class(es) are used to display the tables header

captionClass (only with JSF 1.2):


The " columnClasses " attribute allows defining CSS style listing for each column. In order to define CSS
classes for a column, you have to put a space between each one:
class1.1 class1.2 class1.3 ...

To declare CSS classes for each column, you have to use a comma:
class1.1 class1.2 class1.3, class2 class2.1, class3, class4 class4.1 class 4.2

In this case, the table...

has 4 columns

CSS classes " class1.1 ", " class1.2 " and " class1.3 " are used for the first column

" class2 " and " class2.1 " for the second

" class3 " for the third

" class4.1 " and " class4.2 " for the fourth.
If there is not the same number of CSS classes groups and columns:

If there are more columns than CSS classes groups, then CSS classes groups are reused for the following
columns.
If there are less columns than CSS classes groupes, useless CSS classes groups wont be used.
The " rowClasses " attribute allows defining CSS classes to lines, and it works the same way.
1.5.14.1. Static table: PanelGrid
This kind of array is created with the <h:panelGrid> tag. When you use this table, it means you already know
how many lines and rows you want to display. Indeed, it does not fit well with dynamically generated tables.
In order to define the content of a table, you have to nest tags inside.
Example:
101
Created by XMLmind

XSL-FO Converter.

[CODE:xhtml]<h:panelGrid border="1" columns="2">


<h:outputText value="A" />
<h:outputText value="B" />
<h:outputText value="C" />
<h:outputText value="D" />
</h:panelGrid>

We described the cells starting from upper left to bottom right. There is no tag which defines the beginning or
the end of a line. JSF define the position of each component according the order in which it is declared. As there
are 2 columns, and 4 components, we can assume there is 2 lines.
It displays the following table:

Table 2.6.
A

Now, if you want to display 3 columns, a new line will be created for each after 3 tags:
[CODE:xhtml]<h:panelGrid border="1" columns="3">
<h:outputText value="A" />
<h:outputText value="B" />
<h:outputText value="C" />
<h:outputText value="D" />
</h:panelGrid>

It displays the following table:

Table 2.7.
A

D
1.5.14.1.1. Group elements
If you want to use many tags inside the same cell, you have to group them inside the <h:panelGroup> tag.
Example:
[CODE:xhtml]<h:panelGrid columns="2" border="1" rules="all">
<h:outputText value="A" />
<h:panelGroup>
<h:outputText value="B" />
<f:verbatim><br /></f:verbatim>
<h:outputText value="B bis" />
</h:panelGroup>
<h:outputText value="C" />
<h:outputText value="D" />
</h:panelGrid>

The following code is generated:


[CODE:xhtml]<table border="1" rules="all">
<tbody>
<tr>
<td>A</td>
<td>B<br />B bis</td>
</tr>
<tr>
<td>C</td>
<td>D</td>
</tr>
</tbody>
</table>

1.5.14.1.2. Header and footer


102
Created by XMLmind

XSL-FO Converter.

A header or a footer is defined with a <f:facet> tag. It has an attribute called " name " which define which part is
currently written. Available values are the following ones:

" header ", if it is a header

" footer ", if it is a footer

" caption ", if it is a title (only with JSF 1.2)


The <f:facet> tag do not have any child tag, you have to use the <h:panelGroup> tag to nest many tags.
Example:
[CODE:xhtml]<h:panelGrid border="1" columns="2" rules="all">
<f:facet name="header">
<h:outputText value="I am the header!" />
</f:facet>
<f:facet name="footer">
<h:panelGroup>
<h:outputText value="I am the " />
<h:outputText value="footer" />
</h:panelGroup>
</f:facet>
<!--do not work with JSF 1.1-->
<f:facet name="caption">
<h:outputText value="caption" />
</f:facet>
<h:outputText value="A" />
<h:outputText value="B" />
<h:outputText value="C" />
<h:outputText value="D" />
</h:panelGrid>

Below is the returned HTML code:


[CODE:xhtml]<table border="1" rules="all">
<thead>
<tr>
<th colspan="2" scope="colgroup">I am the header </th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="2">I am the footer</td>
</tr>
</tfoot>
<tbody>
<tr>
<td>A</td>
<td>B</td>
</tr>
<tr>
<td>C</td>
<td>D</td>
</tr>
</tbody>
</table>

Below is a screenshot

103
Created by XMLmind

XSL-FO Converter.

1.5.14.2. Dynamic table: DataTable


The <h:dataTable> tag allows to generate a table dynamicaly. Indeed, it browses elements like the following
ones:

A JavaBean list

A JavaBean array

A JavaBean

A javax.faces.model.DataModel

A java.sql.ResultSet

A javax.servlet.jsp.jstl.sql.ResultSet

A javax.sql.RowSet
The " value " attribute allows defining which property to browse. Furthermore, " var " attribute is the name
which references the elements of the " value " attribute. Below is an example:
[CODE:xhtml]<h:dataTable value="#{bean.elementList}" var="itemFromTheList" />

To define the content of the table, you have to use the <h:column> tag. Each one set a new column :
[CODE:xhtml]<h:dataTable value="#{bean.elementList}" var="itemFromTheList" />
<h:column>
<%--first column--%>
<h:outputText value="#{itemFromTheList .property1" />
</h:column>
<h:column>
<%--second column--%>
<h:outputText value="#{itemFromTheList .property2}" />
</h:column>
</h:dataTable>

If the list contains five elements, thou the table display five lines.
You can also use the following attributes:

" first " to define the first displayed element

" rows " to define how many elements to display

104
Created by XMLmind

XSL-FO Converter.

1.5.14.2.1. Header and Footer


Like PanelGrid table, headers, footers and titles are defined with <f:facet> tag by nested the <f:facet> tag inside
a <h:column> tag.
Example:
[CODE:xhtml]<h:dataTable id="items" value="#{bean.myList}" var="item">
<h:column>
<f:facet name="header">
<h:outputText value="Property 1" />
</f:facet>
<h:outputText value="#{item .property1 }" />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Property 2" />
</f:facet>
<h:outputText value="#{item .property2 }" />
</h:column>
<f:facet name="footer">
<h:outputText value="I am a footer!"/>
</f:facet>
</h:dataTable>

1.5.14.2.2. Example: Display a database table


Lets finish by an exemple which display a database table inside a JSF table ! We start by writing a JavaBean
which read the database content. Indeed, when an instance is created, a simple " SELECT " request is executed
over a table. Then we will display it inside a <h:dataTable> tag.
Example:
[CODE:java]package com.labosun;
public class DataBaseBean {
private ResultSet personRS;
public DataBaseBean() {
initConnection();
}
//Getter and setter
public ResultSet getPersonRS() {
return personRS;
}
public void setPersonRS(ResultSet personRS) {
this.personRS = personRS;
}
private void initConnection() {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection cnx = DriverManager.getConnection("jdbc:mysql://localhost/jsfCours", "login", "pass");
Statement st = cnx.createStatement();
this.personRS = st.executeQuery("select * from contact");
} catch (Exception e) {
// exception handling (not described here)
}
}
}

Here we declare a bean, inside the JSF "faces-config.xml" configuration file:


[CODE:xml]<managed-bean>
<managed-bean-name>dbBean</managed-bean-name>
<managed-bean-class>com.labosun.DataBaseBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>

Then, the following JSF code uses the ResultSet with <h:dataTable> tag and its "value" attribute:
[CODE:xhtml]<h:dataTable value="#{dbBean.personRS}" var="personDB" rules="all" border="1">
<h:column>

105
Created by XMLmind

XSL-FO Converter.

<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<!-- Retrieve lastname column -->
<h:outputText value="#{personDB['lastName']}" /><br />
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Prnom" />
</f:facet>
<!-- Retrieve firstname column -->
<h:outputText value="#{personDB.firstName}" />
</h:column>
</h:dataTable>

1.5.15. Error messages


When an error append (empty text field, conversion error, etc.) a message is created. It is displayable inside with
<h:message> and <h:messages> tags. This feature is described in the chapter " 8.2 Messages management ". For
the moment, we will only see to display them.
Messages have different importance levels:

" SEVERITY_INFO ", information message (low importance)

" SEVERITY_WARN ", warning message

" SEVERITY_ERROR ", error message

" SEVERITY_FATAL ", fatal message (high importance)


There are 2 kinds of message, which are either specific or global:
The <h:message> tag display a message. Its " for " attribute allows defining which comonent it is related to.
The <h:messages> tag allows displaying all the messages.
These tags have the two following attributes:

Table 2.8.
Attribute

Type

Default value

Description

showDetail

boolean

false

Define
wether
more
information is displayed.

showSummary

boolean

true

Define wether a summary


is displayed.

The <h:messages> tag has also the following ones:

Table 2.9.
Attribute

Type

Default value

Description

globalOnly

boolean

false

Define wether the tag


display
only
global
messages (true) or all the
messages (false).

layout

String

list

It

106
Created by XMLmind

XSL-FO Converter.

allows

defining

Attribute

Type

Default value

Description
specific renderings:

" list " to display


messages in a HTML
list

" table " to display


messages in a HTML
table
Example:
[CODE:xhtml]<h:inputText id="number">
<f:validateLongRange minimum="1" maximum="10" />
</h:inputText>
<h:message for="number"/>
<h:commandButton id="submit" action="success"/>

The <f:validateLongRange> tag allows testing if value is between 1 and 10. Indeed a message is displayed if the
value is not validated.
You can also change the CSS class of your messages :

Table 2.10.
Name

Description

errorClass

CSS class used for " ERROR " level messages.

fatalClass

CSS class used for " FATAL " level messages.

infoClass

CSS class used for " INFO " level messages.

warnClass

CSS class used for " WARN " level messages.

There is also the " errorStyle ", " fatalStyle ", " infoStyle " and " warnStyle " attributes to define directly the
style.

1.6. Server configuration


JSF configuration is set into the " WEB-INF/faces-config.xml " file.
The template of this file is:
[CODE:xml]<?xml version="1.0"?>
<!DOCTYPE faces-config PUBLIC "//Sun Microsystems, Inc.//DTD JavaServer Faces Config 1.0//EN"
"http://java.sun.com/dtd/web-facesconfig_1_1.dtd">
<faces-config>
</faces-config>

With JSF 1.2, the file looks like this:


[CODE:xml]<?xml version='1.0' encoding='UTF-8'?>
<faces-config xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-facesconfig_1_2.xsd"
version="1.2">
</faces-config>

Nested tags allow configuring JSF.

1.6.1. JavaBeans declaration


107
Created by XMLmind

XSL-FO Converter.

To configure JavaBeans and handle them through JSF pages, below is the appropriate declaration:
[CODE:xml]<managed-bean>
<managed-bean-name>nom du bean dans la page JSF</managed-bean-name>
<managed-bean-class>class du bean </managed-bean-class>
<managed-bean-scope>(application|session|request|none)</managed-bean-scope>
<managed-property>
<property-name>nom de la proprit </property-name>
<property-class>type de la proprit </property-class>
<value>valeur par dfaut </value>
</managed-property>
</managed-bean>

" managed-bean-name " is the JavaBean name to reference it from JSF pages.

" managed-bean-class " is the fully qualified name of the JavaBean class.

" managed-bean-scope " define the scope of your JavaBean (either request, session, application or none).

" managed-property " initialize a property of your managed bean.


Available scope values are the following:

" application " means your JavaBean instance is reachable for all the users.

" session " means your JavaBean instance is specific for each user.

" request " means a JavaBean instance is created for each request.

" none " means a JavaBean instance is created each time it is called.
1.6.1.1. List declaration
A list is declared with the <listentries> tag. Then you nest values with <value> tags.
Example:
[CODE:xml]<managed-bean>
<managed-bean-name>cityList</managed-bean-name>
<managed-bean-class>java.util.ArrayList</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
<list-entries>
<value-class>java.lang.String</value-class>
<value>Strasbourg</value>
<value>Bordeaux</value>
<value>Paris</value>
<value>Nice</value>
<null-value/>
</list-entries>
</managed-bean>

Notice you can include a null value thank to the <null-value> tag.
You can also define which class to use with the <value-class> tag.
1.6.1.2. Map declaration

108
Created by XMLmind

XSL-FO Converter.

A "Map" is declared with a <map-entries> tag. For each entry in the map, you have to insert a <map-entry> tag.
This last one has two nested elements which are <key> and <value>.
Example:
[CODE:xml]<managed-bean>
<managed-bean-name>dicoMap</managed-bean-name>
<managed-bean-class>java.util.HashMap</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
<map-entries>
<key-class>type.of.your.class</key-class>
<value-class>type.of.your.value</value-class>
<!--first entry -->
<map-entry>
<key>value of the key 1</key>
<value>value associatied with key 1</value>
</map-entry>
<!--second entry -->
<map-entry>
<key>value of the key 2</key>
<value>value associated with key 2</value>
</map-entry>
</map-entries>
</managed-bean>

Just as list declaration, you can define which class to use. The <key-class> and <value-class> tags define which
class to use as key and value. They are both nested inside the <map-entries> tag.
Finally, it is possible to define a null value with the <null-value> tag.
1.6.1.3. Example: Declaration of a SelectItem list
We already have declared collections, ... now, lets see about SelectItem list. We first created managed beans
with the SelectItem class and entries within:
[CODE:xml]<!--declare a first bean -->
<managed-bean>
<managed-bean-name>city0</managed-bean-name>
<!--this bean is a javax.faces.model.SelectItem class -->
<managed-bean-class>javax.faces.model.SelectItem</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
<!--we define below two entries -->
<managed-property>
<property-name>value</property-name>
<value>Stras</value>
</managed-property>
<managed-property>
<property-name>label</property-name>
<value>Strasbourg</value>
</managed-property>
</managed-bean>
<!--declare a second bean -->
<managed-bean>
<managed-bean-name>city1</managed-bean-name>
<managed-bean-class>javax.faces.model.SelectItem</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
<managed-property>
<property-name>value</property-name>
<value>Lyon</value>
</managed-property>
<managed-property>
<property-name>label</property-name>
<value>Lyon</value>
</managed-property>
</managed-bean>

Then you declare another managed bean with the ArrayList class and entries made of previously declared
"city0" and "city1" managed beans.
109
Created by XMLmind

XSL-FO Converter.

[CODE:xml]<!--Dclaration de la liste -->


<managed-bean>
<managed-bean-name>villes</managed-bean-name>
<managed-bean-class>java.util.ArrayList</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
<list-entries>
<value-class>javax.faces.model.SelectItem</value-class>
<value>#{city0}</value>
<value>#{city1}</value>
</list-entries>
</managed-bean>

As you can see, this syntax is a bit heavy, and it is shorted to write entries directly.

1.6.2. Navigation
Navigation is defined with "navigation rules". Each rules define sources and destinations pages.
[CODE:xml]<navigation-rule>
<from-view-id>/source page</from-view-id>
<navigation-case>
<from-outcome>string returned by an action</fromoutcome>
<to-view-id>/destination page</to-view-id>
</navigation-case>
</navigation-rule>

The " from-view-id " tag defines the source page. Then we can nest as many " navigation-case " as needed and
each one have an "outcome" string and "destination" page.
The " from-outcome " tag is the string returned by a link, a button, a managed bean method, etc. Finally the " toview-id " tag is the destination page.
Take the following example:
[CODE:xml]<navigation-rule>
<from-view-id>/index.jsp</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>
<to-view-id>/buy.jsp</to-view-id>
</navigation-case>
</navigation-rule>

As you can see above, you are creating a navigation rule for the web page "index.jsp". If an action return the
value "success", then the user is being forwarded to " buy.jsp ". You have to use "/ as the beginning of the URL
to refer to the root of the web site. You can insert actions into your web pages with JSF tags and their "action"
attribute:
[CODE:xhtml]Action example with a link:
<h:form>
<h:commandLink action="success" value="Make an order"/>
</h:form>
Action example with a button:
<h:form>
<h:commandButton action="success" value="Make an order"/>
</h:form>

Notice that this declaration works well with the two following JSF declaration, inside "web.xml" file:
[CODE:xml]<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
</servlet-mapping>
[CODE:xml]<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>

110
Created by XMLmind

XSL-FO Converter.

Lets now explore a bit more use cases.


1.6.2.1. Global mapping
It is also possible to define a navigation rule for all your application with the "/*" value as source value.
Example:
[CODE:xml]<navigation-rule>
<from-view-id>/*</from-view-id>
<navigation-case>
<from-outcome>error</from-outcome>
<to-view-id>/error.jsp</to-view-id>
</navigation-case>
</navigation-rule>

In this case, all the pages which returns "error" shall forward the user to the web page "error.jsp". Another
solution is to remove the <from-view-id> tag.
1.6.2.2. Action strings
Lets look a bit further about navigation. There is two main tags, which are <from-action> and <fromoutcome>. They can be used alone or in the same time. Indeed there is three ways to declare navigation rules:

If you only write out the " from-outcome " tag, the string must be equal either to an action attribute value or
the return value of a method.

If you write out the two of them, naviguation would only be true if the method defined inside " from-action "
returns the value specified inside the " from-outcome " tag.

If you only write out the " from-action " tag, the value should be a reference to a method. Whatever the return
value is, navigation is true.
Currently used action strings in " from-outcome " are the following:

Table 2.11.
Outcome

Signification

success

It worked correctly

failure

Error during page rendering

logon

User should be redirected to login page.

no results

Research did not return any result. Return to the search


form.

1.6.2.2.1. From-outcome
It is the tag we used in the previous examples. You can also call a method from a managed-bean and analyse its
return value. Below is a method example:
[CODE:java]public String methodName();

Then, write out the following component:


[CODE:xhtml]<h:commandLink action="#{bean.method}" value="Vers la page xxx"/>

Lets take a full example first we define the following rule:


[CODE:xml]<navigation-rule>
<from-view-id>/index.jsp</from-view-id>
<navigation-case>
<from-outcome>success</from-outcome>

111
Created by XMLmind

XSL-FO Converter.

<to-view-id>/achat.jsp</to-view-id>
</navigation-case>
</navigation-rule>

... then a method from a managed-bean returns " success ".


[CODE:java]public class NaviBean {
public String getSuccessString() {
return "success";
}
}

... and finally we write out the JSF link component in the page " index.jsp ":
[CODE:xhtml]<h:form>
<h:commandLink value="Vers la page achat" action="#{navi.getSuccessString}"/>
</h:form>

Notice: "navi" is the name of our managed-bean.


1.6.2.2.2. From-action and from-outcome
Lets illustrate " from-action " and " from-outcome " with the following example:
[CODE:xml]<navigationrule>
<from-view-id>/index.jsp</from-view-id>
<navigation-case>
<from-action>#{navi.validateOrder} </from-action>
<from-outcome>order</from-outcome>
<to-view-id>/order.jsp</to-vie-wid>
</navigation-case>
<navigation-case>
<from-action>#{navi.validateOrder} </from-action>
<from-outcome>mustLogin</from-outcome>
<to-view-id>/login.jsp</to-view-id>
</navigation-case>
</navigation-rule>

We used <from-action> twice but the value nested inside <from-outcome> will allow to create different
navigation cases.
If the method returns any other string than "order" or "mustLogin", the user is not redirected and he stays on the
same page.
In order to use this navigation case, you have to use an action attribute with a reference to a method, like
displayed below:
[CODE:xhtml]<h:commandLink value="Valide les achats" action="#{navi.validateOrder}"/>

Here a example of method you could write:


[CODE:java]public class NaviBean {
public String valideAchat() {
Random r = new Random();
int choice = r.nextInt(2);
if( choice == 0) {
return "order";
} else {
return "mustLogin";
}
}
}

1.6.2.2.3. From-action
With this tag, you only specify which method to use:
[CODE:xml]<navigation-rule>
<from-view-id>/index.jsp</fro-mview-id>
<navigation-case>

112
Created by XMLmind

XSL-FO Converter.

<from-action>#{navi.validateOrder}</from-action>
<to-view-id>/order.jsp</to-view-id>
</navigation-case>
</navigation-rule>

Above, whatever the return value is, the user returns to the "order.jsp" page.
Below is an action attribut which call the validateOrder() method:
[CODE:xhtml]<h:commandLink action="#{navi.valideOrder}" />

1.6.2.3. Example
Lets finish this chapiter by a comprehensive example of navigation rules. The purpose of the following web site
is to manage a list. Indeed you have to write a managed-bean with a List<String> typed object.
This web site is composed of the following pages:

" list.jsp " is the main page, it displays all the entries of the list. It also displays links to remove and modify
them.

" detail.jsp " displays all the information of an entry. It also displays links to the list and delete page.

" delete.jsp " allows to remove an entry, it displays a confirmation message and redirect the client to the list
page.

" new.jsp " allows to create a new entry inside the list. Elle possde un lien vers la page principale.
When you want to remove an entry, you have to pass the entry parameter inside the request, as you saw on the
chapter " 5.6.3 Parameters ".
Below are navigation rules:
[CODE:xml]<navigation-rule>
<from-view-id>/list.jsp</from-view-id>
<navigation-case>
<!--link with the detail page >
<from-outcome>edit</from-outcome>
<to-view-id>/edit.jsp</to-view-id>
</navigation-case>
<navigation-case>
<!--link with the remove page >
<from-outcome>delete</from-outcome>
<to-view-id>/delete.jsp</to-view-id>
</navigation-case>
<navigation-case>
<!--link with the creation page >
<from-outcome>new</from-outcome>
<to-view-id>/new.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/delete.jsp</from-view-id>
<navigation-case>
<!--link with the main page >
<from-outcome>success</from-outcome>
<to-view-id>/list.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/new.jsp</from-view-id>
<navigation-case>
<!--link with the creation page >

113
Created by XMLmind

XSL-FO Converter.

<from-outcome>success</from-outcome>
<to-view-id>/list.jsp</to-view-id>
</navigation-case>
</navigation-rule>
<navigation-rule>
<from-view-id>/edit.jsp</from-view-id>
<navigation-case>
<!--link with the delete page >
<from-outcome>delete</from-outcome>
<to-view-id>/delete.jsp</to-view-id>
</navigation-case>
<navigation-case>
<!--link with the list page >
<from-outcome>list</from-outcome>
<to-view-id>/list.jsp</to-view-id>
</navigation-case>
</navigation-rule>

Below is the managed-bean that you will use:


[CODE:java]public class NaviExampleBean {
private List<String> elements; // a list with entries
private String newElt; // used during entries handling
/**
* Initialize an entries list with default values
*/
public NaviExempleBean() {
this.elements = new ArrayList<String>();
elements.add("salad");
elements.add("ham");
elements.add("peach");
elements.add("tomato");
elements.add("potato");
}
// Getters and setters
...
/**
* Create a new entry, and add it to the list.
* @return success if it complete or failure else.
*/
public String create() {
if (newElt != null) {
this.elements.add(newElt);
newElt = null;
return "success";
} else {
return "failure";
}
}
/**
* Remote the entry whom value is equal to the parameter "idElt".
* @return success when it complete.
*/
public String delete() {
String element = FacesContext.getCurrentInstance()
.getExternalContext().getRequestParameterMap().get("idElt");
FacesMessage fm;
if (element != null) {
elements.remove(element);
fm = new FacesMessage(FacesMessage.SEVERITY_INFO, "Remove complete", "");
} else {
fm = new FacesMessage(FacesMessage.SEVERITY_INFO, "Remove failed", "");
}
FacesContext.getCurrentInstance().addMessage(null, fm);
return "success";
}
}

114
Created by XMLmind

XSL-FO Converter.

And its declaration


[CODE:xml]<managed-bean>
<managed-bean-name>naviEx</managed-bean-name>
<managed-bean-class>com.labosun.NaviExampleBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>

" list.jsp " page:


[CODE:xhtml]<f:view>
<h:form>
<h1>Liste</h1>
<!--allows to display error messages -->
<h:messages />
<h:dataTable value="#{naviEx.elements}" var="elt" rules="all" border="1">
<h:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{elt}" />
</h:column>
<h:column>
<!-- link to delete -->
<h:commandLink value="Delete" action="delete">
<!-- send the parameter idElt to the delete page >
<f:param name="idElt" value="#{elt}" />
</h:commandLink>
</h:column>
<h:column>
<!-- Link to edit -->
<h:commandLink value="edit" action="edit">
<!-- we pass the parameter idElt inside the edit page -->
<f:param name="idElt" value="#{elt}" />
</h:commandLink>
</h:column>
</h:dataTable>
<h:commandLink value="Create a new entry" action="new" />
</h:form>
</f:view>

You can see below its display:

" edit.jsp " page:


[CODE:xhtml]<f:view>
<h:form>
<!-- you retrieve the idElt parameter and display the related entry -->
<h:outputText value="More information about #{param['idElt']}" /><br />
<h:commandLink value="Remote this entry" action="delete">
<f:param name="idElt" value="#{param['idElt']}" />
</h:commandLink>
<h:commandLink value="Return and cancel" action="list" />
</h:form>
</f:view>

Below is the result:

115
Created by XMLmind

XSL-FO Converter.

" new.jsp " page:


[CODE:xhtml]<f:view>
<h:form>
<h1>New entry</h1>
<h:inputText id="name" value="#{naviEx.newElt}">
<h:outputLabel for="name" value="Name:" />
</h:inputText>
<h:commandButton value="Validate" action="#{naviEx.create}" /><br />
<h:commandLink value="Cancel" action="success" />
</h:form>
</f:view>

Below is the rendering:

" delete.jsp " page:


[CODE:xhtml]<f:view>
<h:form>
<!-- You retrieve idElt to known which entry remove -->
<h:outputText value="Do you want to remove the entry: #{param['idElt']} ?" />
<h:commandLink value="Yes" action="#{naviEx.delete}">
<!-- you pass the parameter idElt to inform the managed-bean which entry remove -->
<f:param name="idElt" value="#{param['idElt']}" />
</h:commandLink>
<h:commandLink value="No" action="success" />
</h:form>
</f:view>

1.6.3. Context parameters


You can configure JSF through its context parameters in the "web.xml" file.
[CODE:xml]<context-param>
<param-name>Parameter name</param-name>
<param-value>Parameter value</param-value>
</context-param>

Below are common parameters:

Table 2.12.
javax.faces.CONFIG_FILES

Define which files, separated by a comma, configure


the JSF container. By default, JSF only look inside the
" faces-config. xml " file.

javax.faces.DEFAULT_SUFFIX

Default extension of JSF pages. By default, the value


is " .jsp "

javax.faces.LIFECYCLE_ID

Allows to define which class manage the life cycle of


JSF.
The
default
value
is:
LifecycleFactory.DEFAULT_LIFECYCLE

javax.faces.STATE_SAVING_METHOD

Allows to define which facility save data. There are


two available values:

116
Created by XMLmind

XSL-FO Converter.

" server ", data is saved inside the user session

" client ", data is saved on the client side, as hidden


fields.
The default value is " server ".

1.7. Behavior
1.7.1. ActionListener
All the components which implement "ActionSource" (UICommand) can generate an event. This means a
method is called when the user clicks on an element. The event is treated server side, when the client sends the
page to the server.
Here for recall the cycle of life of a JSF request :

The events of type ActionListener are treated during the phase "Invocation of the application". If the component
which declares the event has the attribute "immediate" set to true, the event is treated during the phase "Request
parameters appliction". Attention however, because during this phase, all the elements are not yet up to date (the
javabeans are only updated during the phase "Update model"). The elements update order is the order of the tag
declaration. There are 2 manners of dealing with server side events. The first solution is to associate a method of
a generic JavaBean. Second is to create an implementation of the interface "ActionListener".
1.7.1.1. Generic method
To create a method which manages an event, it is necessary that it has the following prototype :
[CODE:java]public void methodName(javax.faces.event.ActionEvent e);

The method can be in any bean, but it must be referred as a managed bean by the container. To use the method
you only have to refer to it by using the attribute "actionListener".
Example:
[CODE:xhtml]<h:commandButton value="Send" actionListener="#{beanName.methodName}" />

1.7.1.2. ActionListener interface


It is also possible to create a class which implements "javax.faces.vent.ActionListener". There is just the method
"processEvent (ActionEvent)" to implement.
Example:
[CODE:java]package listeners;
public class EventHandling implements ActionListener {
public void processAction(ActionEvent actionEvent) {
// Event handling
}
}

This ActionListener can be referred in 2 different ways. It is possible to use the attribute "actionListener" as
mentioned previously. But we can also use the tag <f:actionListener>. The "type" attribute of this tag makes it
possible to specify the class of the used ActionListener.
Example:
[CODE:xhtml]<h:commandLink value="with an interface">
<f:actionListener type="listeners.EventHandling" />

117
Created by XMLmind

XSL-FO Converter.

</h:commandLink>

1.7.2. ValueChange Listener


The components which implement "EditableValueHolder", i.e. all the child classes of UIInput
(UISelectBoolean, UISelectMany, UISelectOne) have a value which can be edited by the user. When the page is
sent to the server, all the modified values are generating a server side event. The management of this event is
similar to ActionListener.
Here for recall the cycle of life of a JSF request:

The events of type ValueChangeListener are treated during the phase "Validation of the user entries". If the
component which declares the event has the attribute "immediate" set to true, the event is treated during the
phase "Request parameters application". In that case, all the conversion operations and validations related to this
component will be carried out before the ValueChangeListener management.
Be careful however, because during this phase, not all the elements are yet up to date (the javabeans are only
updated during the phase "model update"). The elements update order is the order of the tag declaration.
1.7.2.1. Generic method
A method which manages the event must have the following prototype:
[CODE:java]public void check(javax.faces.event.ValueChangeEvent event);

The JavaBean which declares the method must be referred as JavaBean managed by the container.
The method can then be referred thanks to the attribute "valueChangeListener".
[CODE:xhtml]<h:inputText valueChangeListener="#{beanName.methodName}" />

1.7.2.2. ValueChangeListener Interface


The other solution consists in implementing "javax.faces.vent.ValueChangeListener" and to redefine the method
"processValueChange (ValueChangeEvent)".
Example :
[CODE:java]package listeners;
public class BeanValueChangeListener implements ValueChangeListener {
public void processValueChange(ValueChangeEvent event) {
// event handling
}
}

This listener can be referred either thanks to the attribute "valueChangeListener" as seen previously, either
thanks to the tag <f:valueChangeListener>. The "type" attribute of this one makes it possible to specify the class
of the used listener.
Example:
[CODE:xhtml]<h:inputText value="value">
<f:valueChangeListener type="listeners.BeanValueChangeListener" />
</h:inputText >

1.7.3. Data conversion


The JSF components which implement ValueHolder (all the child classes of UIOutput) have a value. This value
can be a date, a number, an email, There are no restrictions on the value which can be associated to a
component under condition that the value can be converted form an Object into a String and conversely. This
transformation is necessary, because during the phase "Request parameters application", the JSF Servlet must be
118
Created by XMLmind

XSL-FO Converter.

able to rebuild the object which represents the value of the client request (which is in the form of a String).
Then, at the time of the return phase, the object must be translated into a String. JSF manages the conversion of
the primitives and the standard objects of Java: Boolean, Number
All the conversion operations are carried out at the time of the phase "Request parameters application".

This principle of conversion also makes it possible to personalize the posting of the objects. For example a date
canbe posted in the format "DD/MM/AAAA" or with the day in full letters.
The conversions errors can be posted with the tag <h:message>.
1.7.3.1. Standard conversion: Date
The tag <f:convertDateTime> ensures the conversion Date String. By default, a date is posted in a following
way: "Sat Jul 22 12:56: 12 CEST 2006" what corresponds to Saturday July 22, 2006.
The tag <f:convertDateTime> has the following attributes:

Table 2.13.
Attribute

Type

Description

dateStyle

String

Defines the date format. The values


are: default, short, medium, long et
full For the date Saturday 22th july
2006 the different values are:

default: " Sat Jul 22 13:05:30


CEST 2006 "

short: " 22/07/06 "

medium: " 22 juil. 2006 "

long: " 22 juillet 2006 "

full: " samedi 22 juillet 2006 "


timeStyle

String

Defines the time format. The values


are: default, short, medium, long and
full

locale

String or Locale

The local for representing the date

timeZone

String or TimeZone

Defines the time zone for which one


represents the date.

pattern

String

Allows defining a personalized date


format. It is necessary to use a
pattern which is defined in the
documentation
of
the
class
"SimpleDateFormat"of J2SE. If this
attribute is defined, it is used instead
of dateStyle and timeStyle.

type

String

Allows specifying if the value to be


119

Created by XMLmind

XSL-FO Converter.

Attribute

Type

Description
represented is a date, a time or both.
The values are: date (by default),
time and both.

Example:
[CODE:xhtml]<h:inputText value="#{bean.date}">
<f:convertDateTime dateStyle="full" />
</h: inputText >

Now lets see an example of a form which makes it possible to seize a date in the format "dd/mmyy" and which
then transforms the string in a Date object. For that it is necessary to use the attribute "pattern" and to define the
date format to be used. In our case it is "dd/MMyy":
[CODE:xhtml]<h:form>
<h:inputText id="date" value="#{bean.date}">
<h:outputLabel for="date" value="Date (dd/mm/yy): " />
<f:convertDateTime pattern="dd/MM/yy" />
</h:inputText>
<h:commandButton value="valider" />
</h:form>

1.7.3.2. Standard conversion : Number


The tag <f:convertNumber > ensures the conversion Number String. This tag has the following attributes :

Table 2.14.
Attribute

Type

Description

currencyCode

String

Code ISO4217 used for monetary


conversions

currencySymbol

String

Monetary symbol.

locale

String or Locale

The local to represent the number.

integerOnly

boolean

If "true" only the whole part of the


number will be considered.

maxFractionDigits

int

Maximum number of digits after the


comma.

minFractionDigits

int

Minimum number of digits after the


comma.

maxIntegerDigits

int

Maximum number of digits before


the comma.

minIntegerDigits

int

Minimum number of digits before


the comma.

type

String

Defines what the number represents.


The possible values are: Number
(default value), currency, percentage.

1.7.3.3. Custom convertor


If the base converters are not enough for you, it is possible to create your own. You only have to implement
"javax.faces.convert.Converter".
The 2 methods to be redefined are:
[CODE:java]/**
* @param value This string value is used to create/retrieve an object
*/
Object getAsObject(FacesContext context, UIComponent component, String value);
/**
* @param value This object is used to create/retrieve an object

120
Created by XMLmind

XSL-FO Converter.

*/
String getAsString(FacesContext context, UIComponent component, Object value);

The 2 methods have as parameter the FacesContext instance and the component for which one the conversion is
done. Before being able to use this converter, it should be declared. That is made in the file "faces-config. xml"
using the tag <converter>.
Example:
[CODE:xml]<converter>
<description>Mon premier convertisseur</description>
<converter-id>myConv</converter-id>
<converter-class>com.labosun.converter.MyConverter</converter-class>
</converter>

The tag <description> makes it possible to give a description to the converter.


The tag <converter-id> will define the identifier of the converter in JSF pages. Finally the tag <converter-class>
represents the class of your converter.
There are 2 manners of using a converter:

thanks to the attribute " converter "

thanks to the attribute <f:converter>.


While passing by the attribute "converter", it is enough to refer the identifier of the converter.
Example:
[CODE:xhtml]<h:outputText value="#{conv.person}" converter="myConv" />

With the tag <f:converter>, the attribute "converterId" must refer the identifier of the converter.
Example:
[CODE:xhtml]<h:outputText value="#{conv.person}">
<f:converter converterId="myConv" />
</h:outputText>

1.7.3.4. Convertor for lists


At the time of the chapter on Checkbox, Radio Buttons, lists and Combobox, we saw that it was necessary to
use a converter to store personalized objects. For recall, the tags concerned are:

selectManyCheckbox

selectOneRadio

selectOneListBox, selectManyListBox

selectOneMenu
In this example, we will use the tag selectOneRadio which will make it possible to choose between several
instances of the following class "Persson":
[CODE:java]public class Person {
public static int IDS = 0;
private int id;

121
Created by XMLmind

XSL-FO Converter.

private String lastName;


private String firstName;
public Person(int id, String firstName, String lastName) {
this.id = id;
this.lastName = lastName;
this.firstName = firstName;
}
//Getters et setters for all the properties
...
public String toString() {
if (firstName.length() > 1) {
return this.firstName + " " + this.lastName;
} else {
return this.lastName;
}
}
}

This class simply defines a person who has a unique identifier, a name and a first name..
We will now define the bean which will define the list of SelectItem. We will start by seeing what happens
without data converter.
[CODE:java]package com.labosun;
public class PersonConv {
/**
* This list simulat at data source
*/
public static final List<Person> PERSONS_LIST = new ArrayList<Person>();
static {
PERSONS_LIST.add(new Person(1, "Jo", "Johnson"));
PERSONS_LIST.add(new Person(2, "Raymond", "Schmitt"));
PERSONS_LIST.add(new Person(3, "Bob", "LeNain"));
}
/**
* SelectItem list which return the content of a select request ....
*/
private List<SelectItem> allPersons;
/**
* A person currently selected
*/
private Person person;
public PersonConv() {
allPersons = new ArrayList<SelectItem>();
for (int i = 0; i < PERSONS_LIST.size() 1;i++) {
Person p = PERSONS_LIST.get(i);
this.allPersons.add(new SelectItem(p, p.toString()));
}
Person p = new Person(3, "Bob", "LeNain");
this.allPersons.add(new SelectItem(p, p.toString()));
}
//Getters et setters for all the properties
...
}

The constructor creates a list of SelectItem (Al) from our list of people (PERSON_LIST). But the last instance
of people is not taken out of the list, this is voluntary, you will understand later why. Here now our JSF page. It
contains as many radio buttons as there are people in the list and it posts the currently selected element
[CODE:xhtml]<h:form>
<h:selectOneRadio id="persRadio1" value="#{personList.person}">
<f:selectItems value="#{personList.allPersons}" />
</h:selectOneRadio>
<h:message for="persRadio1" />
<br />
Rsultat:
<h:outputText value="#{personList.person}" />
<br /><br />

122
Created by XMLmind

XSL-FO Converter.

<h:commandButton value="Valider" />


</h:form>

The result :

If you try to validate, the following error occurs:

Notice: error message should be displayed in English if your web browser is configurer in English. Indeed, JSF
is completely internationalized in almost 10 languages (including Chineese).
Take a look at the following HTML code :
[CODE:xhtml]Jo Johnson <input type="radio" value="Jo Johnson" />
Raymond Schmitt <input type="radio" value="Raymond Schmitt" />
Bob LeNain <input type="radio" value="Bob LeNain" />

We can see here that the value of the radio buttons (attribute value in HTML code) uses the method toString ()
of the class Persson. That means if JSF page is translated into HTML, the objects of type Person are translated
into a String thanks to the method toString (). But when the tree of JSF components must be rebuilt, the JSF
Servlet does not know how to reinstantiate the object Persson from this String. Therefor it is necessary to create
a converter which will take care of this translation.
To create the converter, we are using the "Person" identifier.
[CODE:java]package com.labosun;
public class PersonConv implements Converter {
...
/**
* @param value person " id ".
* @return an object related to the id
*/
public Object getAsObject(FacesContext ctx, UIComponent component, String value) {
int id = Integer.valueOf(value);
for (Person p : PERSONS_LIST) {
if (p.getId() == id) {
return p;
}
}
return null;
}
/**
* @param value A " person " object.
* @return " id " of the person.
*/
public String getAsString(FacesContext ctx, UIComponent component, Object value) {
if (value == null || !(value instanceof Person)) {
return "";
}
return "" + ((Person) value).getId();
}
}

The converter has to be declared:


[CODE:xml]<converter>
<converter-id>persConv</converter-id>

123
Created by XMLmind

XSL-FO Converter.

<converter-class>com.labosun.PersonConv</converter-class>
</converter>

It now remains to refer the converter in our tag selectOneRadio:


[CODE:xhtml]<h:selectOneRadio id="persRadio1" value="#{personList.person}" converter="persConv">
<f:selectItems value="#{personList.allPersons}" />
</h:selectOneRadio>

Everythings works very well for the first 2 instances, but when the 3rd button is selected, the following error
occurs:

If you have a look at the HTML code, we can see:


[CODE:xhtml]Jo Johnson <input type="radio" value="1" />
Raymond Schmitt <input type="radio" value="2" />
Bob LeNain<input type="radio" value="3" />

The radio button value use identifiers related to the objects. The error message specific to the 3rd button occurs
because JSF will check if the object returned by the converter belongs well to the list of the items. This checking
is done using the methods hashCode () and equals ().
In our case, our converter returns instances coming from object "PERSONS_LIST", and then JSF will check if
the returned instances belong tothe list "allPersons". But, remember that only the first 2 instances of the list
"allPersons" come from list "PERSONS_LIST". As the class Persson does not redefine the methods hashCode ()
and equals (), it is those of the class Object which are used. This means that the equality is only based on the
equality of the references (==). So this only works for the 2 first instances.
So that this works for all the cases, it is enough to implement these 2 methods in the class Person:
[CODE:java]public boolean equals(Object o) {
if (o == null || getClass() != o.getClass()) {
return false;
}
return this.getId() == ((Person) o).getId();
}
public int hashCode() {
return this.getId();
}

Now everything works fine. In short it is necessary:

Create a converter (Implement Converter).

Define the converter in "faces-config.xml"

Reference the converter in the tag select.... (attribute converter)

Implement the methods hashCode() and equals()


This example is simply adaptable to a tag of type selectMany...

1.7.4. Validation
JSF makes it possible to validate all the data seized by the user. The validation is only possible for the
124
Created by XMLmind

XSL-FO Converter.

components which implement EditableValueHolder. I.e. the text fields, the checkboxes, the radio buttons, the
lists and the comboboxes.

The validation is carried out during the phase "Validation of the user entries". Attention, during this one, all the
elements are not yet up to date (the javabeans are updated only during the "Update model" phase). If there are
several validations, the order of treatments of the validations is the order of the tag declarations.
Note: If the component which declares the validation has the attribute "immediate" set to true, then the
validation is treated during the phase "Request parameters application". That makes it possible to force a
validation to be done before all the others. For example, a person wishes to be recorded on a site. It must seize
the country and the city in which it lives. The validation of the country can be made immediately to be sure that
the validation of the city is considering the country.
To force the user to seize a value, you can set the attribute "required" to true.
Example:
[CODE:xhtml]<h:inputText required="true" />

To carry out a more precise control on the data, a validator should be used. JSF provides 3 standard validateurs.
They are usable thanks to the tags:

<f:validateDoubleRange>, allows to test if a number with comma is in a range.

<f:validateLength>, allows to test the length of a string.

<f:validateLongRange>, allows to test if an integer is in a range.


All these tags have the attributes "minimum" and "maximum" which define the ranges in which a value must be
to be valid.
Example :
[CODE:xhtml]<h:form>
...
<h:inputText id="name">
<h:outputLabel for="name" value="Name:" />
<f:validateLength minimum="3" maximum="10" />
</h:inputText>
<%-- Display a validation message --%>
<h:message for="name" />
...
</h:form>

Here the entire form will not be validated if the value entered for this field text does not have a length ranging
between 3 and 10.
The validation errors are posted by the tag <h:message>.
1.7.4.1. Custom validator
It is possible to create its own validator. There are 2 manners of making it, either by using a method, either by
implementing the interface " javax.faces.validator.Validator ".
1.7.4.1.1. Generic method
Any JavaBean can declare the method, but it must be referred as JavaBean is managed by the container.
125
Created by XMLmind

XSL-FO Converter.

The method which manages the validation must have the following prototype:
[CODE:java]public void validate(javax.faces.context.FacesContext context, javax.faces.component.UIComponent
component, Object value) {
//Event handling
}

If there is a validation error, the method must throw a "javax.faces.Validator.ValidatorException". The


constructor takes as parameter an object of type "javax.faces.application.FacesMessage", i.e. a message which is
intended for the user. This message will then be posted thanks to the tag <h:message>.
The method can then be referred thanks to the attribute " validator ".
[CODE:xhtml]<h:inputText validator="#{nomDuBean.methodName }" />

1.7.4.1.2. Interface
It is necessary to implement the interface javax.faces.validator.Validator . The only method to redefine :
[CODE:java]public void validate(FacesContext context, UIComponent component, Object value);

To use this validator, it should be declared in the file "faces-config. xml" using the tag <validator>.
Example :
[CODE:xml]<validator>
<!-- validator identifier -->
<validator-id>emailValidator</validator-id>
<!-- validator class -->
<validator-class>com.labosun.validation.EmailValidator</validator-class>
</validator>

The validator can then be used thanks to the tag <f:validator>, the attribute "validatorId" must refer the identifier
of the validator.
Example :
[CODE:xhtml]<h:inputText>
<f:validator validatorId="emailValidator" />
</h:inputText>

1.7.4.2. Example: Email validator


To illustrate the operation of a validation, we will create a very basic email validator. We will just check the
presence of the character @ .
[CODE:java]public void validate(FacesContext context, UIComponent component, Object value) throws
ValidatorException {
if ((context == null) || (component == null)) {
throw new NullPointerException();
}
if (value != null) {
String field = (String) value;
if (field.contains("@") == false) {
FacesMessage fm = new FacesMessage("Email is not compliant");
throw new ValidatorException(fm);
}
}
}

We are now declaring our bean in the file faces-config.xml .


[CODE:xml]<managed-bean>
<managed-bean-name>beanMail</managed-bean-name>
<managed-beanclass>com.labosun.EmailValidator</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>

The last thing to do is to write the code of the page and to refer the method of our bean by using the attribute
126
Created by XMLmind

XSL-FO Converter.

Validator.
[CODE:xhtml]<h:form>
<h:inputText id="emailMethod" validator="#{beanMail.checkEmail}">
<h:outputLabel for="emailMethod" value="Email:" />
</h:inputText>
<h:message for="emailMethod" />
<br />
<h:commandButton value="Vrifier l'email" />
</h:form>

If a text which was entered does not contain an "@", the tag <h:message> posts the message "an email must
contain an @"..

1.8. Advanced concept


1.8.1. Internationalization
The internationalization of JSF pages is done with properties file. A properties file is a list of keys / values. See
the
tutorial
of
Sun
for
more
informations
on
properties
file
here
:
http://java.sun.com/docs/books/tutorial/i18n/index.html.
To use a properties file in a JSF page, the <f:loadBundle> tag is used like this :
[CODE:xhtml]<f:loadBundle basename="fileName" var="variable" />

The attribute basename indicate the name of the properties file who will be used. Caution, if the file is in a
package, you will need to prefix the file by the package name. The attribute var will be used in the page to
reach the ressources file.
We reach one key defined in the ressources file like this :
[CODE:xhtml]<h:outputText value="#{variable.keyName}" />

Example:
We have a properties file called SiteMessages.properties in the com.labosun package. This properties file
contains this line :
message=hello

To use it in a page, this code will be used :


[CODE:xhtml]<f:loadBundle basename="com.labosun.SiteMessages" var="msg"/>
<f:view>
<h:outputText value="#{msg.message}"/>
</f:view>

In this case, the locale used will be the locale of the users. If you want to change the default locale, you need to
use this code in the file faces-config.xml :
[CODE:xml]<application>
<localeconfig>
<defaultlocale>en</defaultlocale>
</localeconfig>
</application>

The chapter 8.1.3 Example: Change language button explain how change the locale.
1.8.1.1. Dynamic internationalization
It is sometimes need to reach a properties file from a JavaBean. To do this, it is necessary to use the getBundle
method from the RessourceBundle method. The first attribute of this method is the name of the properties file,
and the second is the locale we want to use.
[CODE:java]FacesContext context = FacesContext.getCurrentInstance();
String basename = "conf.SiteMessages";

127
Created by XMLmind

XSL-FO Converter.

String key = "dynamicMessage";


String message;
try {
ResourceBundle bundle = ResourceBundle.getBundle(basename, context.getViewRoot().getLocale());
} catch (Exception e) {
// exception handling
}
// retrieving a localized message
message = bundle.getString(key);

1.8.1.2. Encoding
Normalement la notion dencodage a dj t vue dans le cours JSP, mais pour rappel, il est possible de changer
lencodage des pages grce la directive de page :
The encoding concept has already been seen, but for recall, it is possible to change the encoding of apages with
the following attributes:
[CODE:xml]<%@ page pageEncoding="UTF8" contentType="text/html; charset=UTF8" %>

By default it is the value ISO-8859-1 which is used. The list of available encoding is on the page:
http://java.sun.com/j2se/1.4.2/docs/guide/intl/encoding.doc.html
1.8.1.3. Example: Change language button
In this example, we will sight how changed the site language, when an user click on a link. Starting with make
the Web page. The current locale will be shown and 4 link will perform the language change.
[CODE:xhtml]<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<html>
<body>
<f:view>
<%-- We load the properties file --%>
<f:loadBundle basename="com.labosun.i18n.ChangeLocaleRB" var="change" />
<%-- Print the current locale --%>
<h:outputText value="#{change.currentLocale} #{changeBean.changeLocale}" />
<br />
<h:form>
<%-- Link to change language --%>
<h:commandLink id="FR" value="#{change.french}"
actionListener="#{changeBean.changeLocale}" /><br />
<h:commandLink id="US" value="#{change.english}"
actionListener="#{changeBean.changeLocale}" /><br />
<h:commandLink id="CA" value="#{change.canadian}"
actionListener="#{changeBean.changeLocale}" /><br />
<h:commandLink id="DE" value="#{change.deutsch}"
actionListener="#{changeBean.changeLocale}" /><br />
</h:form>
</f:view>
</body>
</html>

This page use properties files. Here is the contents of 2 properties files ( english and french ) :
File ChangeLocaleRB_fr.properties :
currentLocale=La Locale actuelle est
french=Franais
english=Anglais
canadian=Canadien
deutsch=Allemand

File ChangeLocaleRB_en.properties :
currentLocale=The current Locale is
french=French
english=English

128
Created by XMLmind

XSL-FO Converter.

canadian=Canadian
deutsch=Deutsch

We need now to write the JavaBean who will perform the language change :
[CODE:java]package com.labosun.i18n;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import java.util.Locale;
public class ChangeBean {
/**
* Contains the current locale
*/
private Locale currentLocale = FacesContext.getCurrentInstance().
getViewRoot().getLocale();
public Locale getCurrentLocale() {
return currentLocale;
}
/**
* Change the locale of the current view.
* @param newLocale La nouvelle Locale
*/
public void setCurrentLocale(Locale newLocale) {
FacesContext.getCurrentInstance().getViewRoot().setLocale(newLocale);
this.currentLocale = newLocale;
}
public void changeLocale(ActionEvent ae) {
String id = ae.getComponent().getId();
Locale newLocale = null;
// we get all available locale
Locale[] locales = Locale.getAvailableLocales();
for (int i = 0; newLocale == null && i < locales.length; i++) {
if(locales[i].getCountry().equals(id)) {
newLocale = locales[i];
}
}
if (newLocale == null) {
newLocale = Locale.getDefault();
}
setCurrentLocale(newLocale);
}
}

Then we must declare this Javabean in the file: faces-config. xml :


[CODE:xml]<faces-config>
<managed-bean>
<managed-bean-name>changeBean</managed-bean-name>
<managed-bean-class>com.labosun.i18n.ChangeBean</managed-bean-class>
<managed-bean-scope>application</managed-bean-scope>
</managed-bean>
</faces-config>

1.8.2. Messages management


As seen at the chapter 5.15 Error message , all errors are moved up to the user via a message system. Here, it
is possible since any type of JavaBean (actionListener, converter, validation, ...) to send a message who will be
printed in a page. A JSF message is represent by the javax.faces.application.FacesMessage class. Each
message have a summray of the error ( properties summary ), a detail of the error ( properties detail ),
and the severity of the error ( properties severity ). Messages are saved in the application with the
addMessage(String clientId, FacesMessage message) method of the FacesContext class. The attribute
cliendId allows to link the message to acomponent, if its null, then it is a global message. To have a valid
identifier, the easiest way is to get directly the component identifier with the UIComponent.getId() method.
Let us see now an example of making messages from a Javabean:

129
Created by XMLmind

XSL-FO Converter.

[CODE:java]package com.labosun.message;
import javax.faces.application.FacesMessage;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
public class MessageBean {
private UIInput nameInput;
public UIInput getNameInput() {
return nameInput;
}
public void setNameInput(UIInput nameInput) {
this.nameInput = nameInput;
}
public void check(ActionEvent ae) {
FacesContext context = FacesContext.getCurrentInstance();
//Retrieve component id
String nameId = nameInput.getClientId(context);
FacesMessage f = new FacesMessage(FacesMessage.SEVERITY_WARN, "Global message summary", "message
from MessageBean");
context.addMessage(null, f);
FacesMessage f2 = new FacesMessage(FacesMessage.SEVERITY_INFO, "Specific message summmary", "message
from MessageBean and specific to component 'name'");
context.addMessage(nameId, f2);
}
}

The attribute nameInput will be linked with a component for recovered its identifier. The check method is
used as ActionListenener. It is it which make the two messages f and f2 . The first message is global
since one does not use an identifier at the context addition. The second message is specific to the component
nameInput . To link the attribute nameInput with the component of text type in the JSF page, we need to
use the attribute binding .
[CODE:xhtml]<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<html>
<head>
<link href="style.css" rel="stylesheet" type="text/css" />
</head>
<body>
<f:view>
<h:messages globalOnly="true" showDetail="false" showSummary="true"
styleClass="errorTable" errorClass="error"
infoClass="info" fatalClass="fatal" warnClass="warn" />
<h:form>
<h:inputText id="name" size="10" binding="#{messageBean.nameInput}">
<h:outputLabel for="name" value="Name:" />
</h:inputText>
<h:message for="name" styleClass="errorTable" errorClass="error"
infoClass="info" fatalClass="fatal" warnClass="warn" />
<h:commandButton value="Valider" actionListener="#{messageBean.check}"/>
<br />
<h3>List</h3>
<h:messages showDetail="true" showSummary="true"
styleClass="errorTable" errorClass="error"
infoClass="info" fatalClass="fatal" warnClass="warn" />
<h3>Table</h3>
<h:messages showDetail="true" showSummary="false" layout="table"
styleClass="errorTable" errorClass="error"
infoClass="info" fatalClass="fatal" warnClass="warn" />
</h:form>
</f:view>
</body>
</html>

Last stage, we need to save the JavaBean in the faces-config.xml file.


[CODE:xml]<managed-bean>
<managed-bean-name>messageBean</managed-bean-name>
<managed-bean-class>com.labosun.message.MessageBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>

130
Created by XMLmind

XSL-FO Converter.

</managed-bean>

1.8.2.1. Customize messages


The default errors messages not always correspond to your application. Fortunately it is possible to change
these.
In JSF 1.2, all components who inherit of UIInput allows personalization of the message very easily with 3
attributes :

converterMessage : define the message when the value of the component can't be convert.

requiredMessage : define the message when no value is entered.

validatorMessage : define the message used when the entered value is not validated by the component.
For all others messages and for JSF 1.1, the default errors messages are in the Message_fr.properties
properties file, who is in the java.faces package, of jsfimpl.jar jar file. It is impossible to redefine these
messages by creating a new properties file with the same keys. This new file can be anywhere in your
application. We will then define it to replace the default file.
For example, we will create the MyDefaultMessages_fr.properties file, in which, we will copy the
keys/values of the original Message_fr.properties file.
javax.faces.component.UIInput.REQUIRED= Validation error : You must enter a value.
javax.faces.validator.LengthValidator.MAXIMUM= Validation error : the value is superior to the maximum authorized : ,
''{0}''

You will notice that all special characters are unicode. In these messages, syntax "{0}" allows insert of
parameters. This uses the MessageFormat class.
Now, we will put these messages:
javax.faces.component.UIInput.REQUIRED= Personalized message : This field is required.
javax.faces.validator.LengthValidator.MAXIMUM= Personalized message : The value ''{0}'' is superior to the maximum
authorized for this field.

This file is used in place of the default file. It is defined in the JSF configuration file:
[CODE:xml]<faces-config>
<application>
<locale-config>
<default-locale>fr</default-locale>
</locale-config>
<message-bundle>MyDefaultMessages</message-bundle>
</application>
</faces-config>

1.8.3. JSF Integration in JEE application


The new JEE 5 specification bring annotation who can be used for interact with the lower layer of your
application, with the injection principle. For this, we will define a variable who will be create by the container.
We need a JEE 5 valid server to use these annotations.
1.8.3.1. Resource injection
Ressources injection allow by example to get an instance of the JNDI current context. It is used with the
annotation @Ressource .
Example :
[CODE:java]@Resource
private SessionContext ctx;

131
Created by XMLmind

XSL-FO Converter.

With the deployment of application, the variable of "ctx" will be initialized.


1.8.3.2. EJB injection
EJB injection allows getting an instance of Local or Remote interface. It is used with the annotation @EJB .
Example :
[CODE:java]@EJB
private Store store;

Is is also possible to use ressources injection to get an instance on JNDI current context and to seek then the
EJB.
Example:
[CODE:java]@Resource
private SessionContext ctx;
Store store = (Store)ctx.lookup("Store");

1.8.3.3. WebService injection


It is possible to get a WebServices who inherit of javax.xml.ws.Service . Injection is used with the annotation
@WebServiceRef .
[CODE:java]@WebServiceRef
public StockQuoteService stockQuoteService;

1.8.3.4. Persistence unit injection


It is possible to get an instance of one EntityManager. Like in EJB3, injection is done with the annotation
@PersistanceContext . The unitName field allows informing the unit of persistence name to be used. To be
valid, this field must be defined in the persistence.xml file.
Example:
[CODE:java]@PersistenceContext(unitName="InventoryManagement")
EntityManager em;

1.9. Facelets
1.9.1. Introduction
JSF was designed to work with JSP, but it is obvious there are numerous problems when both are mixed. To
only quote one, the unified language EL should be used in two different ways according to the JSP or JSF
context (syntax ${} and #{}).
The Facelets goal is to create a set of tags that are well matched with JSF and also give a new way to write JSF
code. It does not add new internal mechanisms to JSF, but settles to easy the writing of code by letting code
template creation.
Facelets works with the JSF implementations 1.1 and 1.2 of Sun and Apache MyFaces.
Facelets also provides the following enhancements:

Possibility to create pages in several files

More precise display of errors

Quicker creation of custom tags

132
Created by XMLmind

XSL-FO Converter.

Simple configuration

Let to use JSF tags as standard HTML ones (attribute jsfc, see the chapter "JSFC")
To understand what brings Facelets, we have to come back to the life cycle of a Web page. JSF was designed to
be modular, this means it is possible to change some components in the JSF internal. Facelets deals with
replacing view components, ie. the phases "View Restoration" et "Reply Rendering". Other phases stay
unchanged.
Here is a reminder of the life cycle. Yellow parts are managed by Facelets:

Thanks to the control of those two phases, all the syntax of the files can be changed and entirely retought by
Facelets.

1.9.2. Configuration
In this chapter, we will see how to install and configure Facelets to use it in a project.
1.9.2.1. Installation
First of all, you should download the last implementation of Facelets at this address:

https://facelets.dev.java.net/
This lesson is based on version "1.1.11".
You then have to uncompress the archive and get the file "jsf-facelets.jar". In the case where you do not use a
JEE 5 server, you should take the files "el-api.jar" and "el-ri.jar" that are placed in the directory "lib".
1.9.2.2. Project Structure
Facelets respects the same structure as a standard JSF application. The only difference is the extension of Web
pages, it is ".xhtml". This extension is not mandatory, but the syntax of Facelets follow the xHTML format. It is
then more logical to use that extension.
The structure of a War file stays the same as for JSF. Here it is:

Table 2.15.
133
Created by XMLmind

XSL-FO Converter.

WEB-INF/classes

Contains all the Java classes (the JavaBeans, among


others).

WEB-INF/lib

Every libraries (jar) needed by the project. The Facelet


library: "jsf-facelets.jar". Eventually: "el-api.jar" and
"el-ri.jar".

WEB-INF/faces-config.xml

Configuration file.

WEB-INF/web.xml
*.xhtml

All ".xhtml" files should be placed at the root. Those


are Facelets pages.

1.9.2.3. Configuration
We are now going to see modifications to do to the files "faces-config.xml" and "web.xml" pour to be able to
use Facelets.
First of all, we will define the extension ".xhtml" as pages extension. As seen in the chapter "Context parameters
", we shall use the context parameter "javax.faces.DEFAULT_SUFFIX".
[CODE:xml]<web-app>
<!-- Extension .xhtml for JSF pages -->
<context-param>
<param-name>javax.faces.DEFAULT_SUFFIX</param-name>
<param-value>.xhtml</param-value>
</context-param>
<!--Specific parameter to Facelets. Useful for development -->
<context-param>
<param-name>facelets.DEVELOPMENT</param-name>
<param-value>true</param-value>
</context-param>
</web-app>

In the following examples, the suffit ".jsf" is used. This allows to call a page by replacing the extension ".xhtml"
by ".jsf". To remind you, here is how to declare it:
[CODE:xml]<web-app>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>*.jsf</url-pattern>
</servlet-mapping>
</webapp>

We now need the JSF Servlet forward calls to Facelets for the view management. This is done in the file "facesconfig.xml":
[CODE:xml]<faces-config>
<application>
<view-handler>
com.sun.facelets.FaceletViewHandler</view-handler>
</application>
</faces-config>

Thanks to this configuration, the view management (creation of the JSF component tree, rendering of the reply)
will be managed by Facelets and not by the JSF implementation anymore.

1.9.3. Core Concepts


1.9.3.1. Page Structure
The structure of the facelet pages respect the format xHTML. Here is a first example of a Facelets page:
Hello.xhtml :
134
Created by XMLmind

XSL-FO Converter.

[CODE:xml]<?xml version="1.0" encoding="UTF8"?>


<!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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<body>
<h:outputText value="Hello" />
#{param.f}
</body>
</html>

The first different in relation to a classical JSF page is that the taglibs declaration is different.
Here, we declare all the libraries like namespaces in the <html> tag.
The expression "xmlns:ui=http://java.sun.com/jsf/facelets" allows to use all the Facelets tags. Whereas the two
next ones allow to use the JSF libraries.
There is no tag <f:view>. Finally, it is possible to use an EL expression directly in the HTML code. For
instance, the code "#{param.f}" displays directly the value of the parameter "f".
If we execure this page by setting the parameter "f=Facelets" in the URL, we get the text:
Hello Facelets

This is an example assuming "JSFCoursFacelets" if the context of the project and "Hello.jsf" is the name of the
page. We must use the URL: http://localhost:8080/JSFCoursFacelets/Hello.jsf?f=Facelets .
1.9.3.2. JSFC
One of the problems that arise with the JSF tags is that editors do not all know how to render a page in a
graphics way. However, most of code editors know how to display an HTML page.
One of the possibilities offered by Facelets is to display the result of a page as HTML and without it being
executed on the server. This is done thanks to the attribute "jsfc".
Let us see an example:
[CODE:xml]<?xml version="1.0" encoding="UTF8"?>
<!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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
<title>Form with JSFC</title>
</head>
<body>
<form jsfc="h:form">
<input id="name" type="text" jsfc="h:inputText" value="#{bean.name}" required="true">
<label for="name">Name:</label>
</input>
<h:message for="name" />
<br />
<button type="submit" jsfc="h:commandButton" value="Validate" />
</form>
</body>
</html>

Let us take the tag <form jsfc="h:form">, Facelets will do the interpretation as a tag <h:form>, but from a code
editor perspective it is only a simple <form> tag. The attribute "jsfc" serves to define the real type of the tag.
The advantage here is to be able to work with standard HTML tags and let let editors graphically display them
in a simple editor.

135
Created by XMLmind

XSL-FO Converter.

Attributes specifics to a JSF tag should be added to the HTML tag. An HTML editor will certainly indicate that
the attribute does not exist for that tag, but it will work correctly for Facelets. This is the case for the attribute
"required" for the tag <input>.
For the JSF tags that do not have HTML equivalents like the tag <h:message> for instance, we should include it
directly in the code.
We then get a mix of HTML and JSF tags, without forgetting that we always still can add EL expressions
directly in the HTML code.
1.9.3.3. Template
A template is a Facelets code that can be reused. Templates will be applied at wish in the site. this is the
equivalent of a tag, except that a template is written in a very simple manner and is more easily modular. A page
that uses a template is named a "calling page". We will later see that there are several manners to use a template.
This lesson part is only concentrating on the basic declaration of a template.
Every Facelets file can serve as a template. By default, this is all of a page that defines a template.
Template1.xhtml:
[CODE:xml]<?xml version="1.0" encoding="UTF8"?>
<!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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
<title></title>
</head>
<body>
</body>
</html>

Here, the entire page is considered as a template. To only use a portion of code as a template, we must use the
tag <ui:composition>.
Template2.xhtml:
[CODE: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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
<title></title>
</head>
<body>
<ui:composition template="Template1.xhtml">
</ui:composition>
</body>
</html>

The result of this example will be that the content of the page "template1.xhtml" will be displayed on the client.
This example is quite limited because it is equivalent to the inclusion of a page. We will see in the next chapter
how to create and use modifiable templates.
In this example, all the tags of the pages that use the template are ignored. This behavior is specific to the tag
<ui:composition>, the chapter "Facelets" will present other tags to use templates.

1.9.4. View Templating


Now that we understand the basic syntax of Facelets and the concept of templates, we will see how this can be
136
Created by XMLmind

XSL-FO Converter.

done in practice.
One of the most occurring problems during the creation of a Web site is that every page should redefine all the
page layout of the site. Ie. redefine the title, the menu, the footer... Those elements are often the sames for every
pages of the site. It is more practical to only declare them once and that they get integrated directly to other
pages.
Facelets allow to do that thanks to its template system. Let us see how it works with a first example
First of all, we must write the template page. it will describe the structure of the site and the elements that other
pages can modify. In our example, we will create a site that contains a header, a menu, a body and a footer.
MainTemplate.xhtml:
[CODE: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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
<title>
<ui:insert name="Title">Default Title</ui:insert>
</title>
</head>
<body>
<div style="background: cornflowerblue; position: absolute; left: 0%; right:0%; bottom: 95%; top: 0%">
<ui:insert name="Header">
<ui:include src="Header.xhtml" />
</ui:insert>
</div>
<div style="background: darksalmon; position: absolute; left: 0%; right: 90%; bottom: 5%; top: 5%;">
<ui:insert name="Menu">
<a href="">Default Menu 1</a><br />
<a href="">Default Menu 2</a><br />
<a href="">Default Menu 3</a><br />
</ui:insert>
</div>
<div style="position: absolute; left: 10%; right: 0%; bottom: 5%; top: 5%;">
<ui:insert name="Body">
Default Body
</ui:insert>
</div>
<div style="background: lawngreen; position: absolute; left: 0%; right: 0%;bottom: 0%; top: 95%">
<ui:insert name="Footer">
Default Footer
</ui:insert>
</div>
</body>
</html>

There are two tags specific to Facelets in this template page, <ui:insert> and <ui:include>. First, the tags
<ui:insert> allow to define the modifiable parts of the template. Each tag use a name to uniquely identify the
part
In the case of the tag:
[CODE:xhtml]<ui:insert name="Footer">
Default Footer
</ui:insert>

It defines all the footer part that is modifiable. The text "Default Footer" is the text displayed by default, when
another page that use the template to not modify the footer.
For the tag:
[CODE:xhtml]<ui:insert name="Header">
<ui:include src="Header.xhtml" />

137
Created by XMLmind

XSL-FO Converter.

</ui:insert>

It does not define directly the default header, but import a file that contains the default text. The import is done
with the tag <ui:include>.
HeaderTemplate.xhtml:
[CODE: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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
<title></title>
</head>
<body>
<ui:composition>
Default Header
</ui:composition>
</body>
</html>

This page contains the default code for the header. The tag <ui:composition> is used to define a bloc of code
that can be reused in other pages. In fact, all the code that is arround the tag <ui:composition> is ignored, that
means that it will never appear in an HTML page received by the client. This behavior is due to the tag
<ui:include> that ignores the rest of the page as soon as it finds a tag <ui:composition>. We will see the
inclusion principle in detail in the chapter " 1.4.5 Include ".
Our template is now read, we can create the page that will use the template.
PageMain.xhtml:
[CODE: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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
<title>Main Page</title>
</head>
<body>
<ui:composition template="MainTemplate.xhtml">
<!-- A tag define must match a <ui:insert> tag in the template -->
<ui:define name="Title">Main Page</ui:define>
<ui:define name="Footer">Footer</ui:define>
<ui:define name="Body">Redefined body of the page</ui:define>
</ui:composition>
</body>
</html>

The tag " <ui:composition>":


[CODE:xhtml]<ui:composition template="MainTemplate.xhtml">
...
</ui:composition>

It uses the attribute "template". In this case, it does not serve to declare a template (like in
HeaderTemplate.xhtml) but to precise that we want to use an existing bloc of code.
In our case, we begin by taking all the code of the page of the attribute "template", "MainTemplate.xhtml".
Then, we replace the modifiable parts (bodies of the tags <ui:insert>) by the content of the tags <ui:define>.
Here, we do not modify the parts "Title", "Footer" and "Body". The order of the tags "define" does not matter. It
is not mandatory to redefine all parts.

138
Created by XMLmind

XSL-FO Converter.

If "JSFCoursFacelets"

is the context of the project, this page is available at the address:

http://localhost:18080/JSFCoursFacelets/PageMain.jsf
The graphical result is:

Be Careful: In the last page "PageMain.xhtml", every tags <ui:define> that is outside of the dirst
<ui:composition> tag are ignored. Moreover, all the code that is not inside valid <ui:define> tags are also
ignored. Ie. the following code will generate the same HTML page. All grayed parts are not included in the
HTML page that the client receives.
[CODE: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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
<title>Main Page</title>
</head>
<body>
<!-- Ignored tag -->
<ui:define name="Title">Title not took into account</ui:define>
<!-- Only one composition tag is valid -->
<ui:composition template="MainTemplate.xhtml">
<!-- Valid define tag -->
<ui:define name="Title">Main Page</ui:define>
This text is ignored
<!-- Valid define tag -->
<ui:define name="Footer">Footer</ui:define>
<!-- Valid define tag -->
<ui:define name="Body">Redefined body of the main page</ui:define>
</ui:composition>
<!-- Ignored tag -->
<ui:define name="Menu">Menu not took into account</ui:define>
<!-- This composition tag is completely ignored -->
<ui:composition template="MainTemplate.xhtml">
<ui:define name="Menu">Menu</ui:define>
<ui:define name="Body">The body, again.</ui:define>
</ui:composition>
</body>

139
Created by XMLmind

XSL-FO Converter.

</html>

The working of the different tas will be reviewed in detail in the rest of the lesson. It is possible, from this
exemple, to create a skeleton of page that you can reuse as you wish.

1.9.5. Facelets Tags


1.9.5.1. Composition
The tag <ui:composition> allows:

Either to define a template zone,

Or to use a template by eventually adding modifications (using the attribute "template").


1.9.5.1.1. Define a Template
Take the first case to define a template zone. Example:
[CODE:xhtml]<ui:composition>
Reusable part.
</ui:composition>

It is possible to use <ui:insert> tags to define what zones of the template are modifiables.
1.9.5.1.2. Template Usage
A template can be used with the tag <ui:composition>. In this case, the attribute "template" must define the
URL to the files of the template to use. The usage of a template follow those rules:

If the template file contains one or several <composition> tags then only the body of the first tag is took into
account,

Else, all the page is took into account.


In every cases, the code that is arround the tag <composition> in a calling page is not included in the final reply.
See the chapter " 1.3 View Templating " for an example of use where only the calling page use the tag
<ui:composition>. We will see here a second example where the template page and the calling page both use the
tag <ui:composition>.
1.9.5.1.3. Example
TemplateWithComposition.xhtml:
[CODE: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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
<title></title>
</head>
<body>
<ui:composition>
<div style="...">
<ui:insert name="Header">Header</ui:insert>
</div>
<div style="...">

140
Created by XMLmind

XSL-FO Converter.

<ui:insert name="Body">Default body.</ui:insert>


</div>
</ui:composition>
</body>
</html>

UseTemplateWithComposition.xhtml:
[CODE: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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
<title></title>
</head>
<body>
<ui:composition template="TemplateWithComposition.xhtml">
<ui:define name="Header">header</ui:define>
<ui:define name="Body">Redefined body of the main page.</ui:define>
</ui:composition>
</body>
</html>

The result will be:


[CODE:xhtml]<div style="...">
Header
</div>
<div style="...">
Redefined body of the main page.
</div>

Here, we see well that everything that is around the tags <ui:composition> is ignored.
1.9.5.1.4. Insert
The tag <ui:insert> can be used in templates. It defines a portion of code that can be replaced. The attribute
"name" let you identify that portion. The replacing is then done by the tag <ui:define> that have an attribute
"name" too. There only need to match both to do a replacement.
Example:
[CODE:xhtml]<ui:insert name="Partie1">
Modifiable part.
</ui:insert>

It is also possible to use the tag without specifying a name. In this case, all the body of the tags that uses the
template will be included.
Example without name:
ParagraphTemplate.xhtml:
[CODE:xhtml]Start of paragraph
<ui:insert />
End of paragraph

Page.xhtml:
[CODE:xhtml]<ui:composition template="Paragraph.xhtml">
Middle of paragraph
</ui:composition>

The generated page will be:


[CODE:xhtml]Start of paragraph
Middle of paragraph

141
Created by XMLmind

XSL-FO Converter.

End of paragraph

1.9.5.1.5. Define
The tag <ui:define> allow to replace the content of a tag <ui:insert>. It has the mandatory attribute "name" that
must match a name of a <ui:insert> tag.
1.9.5.1.6. Decoration
The tag <ui:decoration> allow to use a template. It works like the tag <ui:composition> except that all the code
of the calling page is included in the reply. We have the same page of template as in the chapter "Example".
TemplateWithComposition.xhtml:
[CODE: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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
<title></title>
</head>
<body>
<ui:composition>
<div style="...">
<ui:insert name="Header">Header</ui:insert>
</div>
<div style="...">
<ui:insert name="Body">Default body</ui:insert>
</div>
</ui:composition>
</body>
</html>

UseTemplateWithDecoration.xhtml:
[CODE: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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
<title>Page principale</title>
</head>
<body>
<ui:decorate template="TemplateWithComposition.xhtml">
<ui:define name="Header">Header</ui:define>
<ui:define name="Body">Redefined body of the main page</ui:define>
</ui:decorate>
</body>
</html>

The result will be:


[CODE: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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
<title>Page principale</title>
</head>
<body>
<div style="...">

142
Created by XMLmind

XSL-FO Converter.

Header
</div>
<div style="...">
Redefined body of the main page
</div>
</body>
</html>

1.9.5.1.7. Include
The tag <ui:include> allow to include a Facelet page. It have the mandatory attribute "src" that designate the
page to include. The name of the page can be wrote directly ou it can be an EL expression.
Example that allow to include the page "Footer.xhtml":
[CODE:xhtml]<ui:include src="Footer.xhtml" />

The inclusion follows those rules:

If the file to include contains one or several tags <composition> then only the content of the first tag is took
into account.

Else, all the page is took into account.


This mechanism is interesting because one page can still define the tag <html> with all the namespaces, that
allow to edit it in an editor.
1.9.5.1.8. Param
The tag <ui:param> allow to pass parameters to a Facelets bloc of code. It can be used inside the tags
<ui:define> and <ui:include>.
It has those two mandatory attributes:

name

value
1.9.5.1.9. Remove
The tag <ui:remove> allow to not take into account all the code that is in its body. This is like a comment on a
whole bloc (like /* and */). But this solution has the advantage to not have to comment every single line of code.
Example:
[CODE:xhtml]<body>
<h:outputText value="affich" />
<ui:remove>
<h:outputText value="Not displayed" />
<form>
<%-- <h:outputText value="Not displayed again" /> --%>
<!-- <input type="text" /> -->
<button type="submit" />
</form>
</ui:remove>
<h:outputText value="Displayed" />
</body>

Here, all the part inside <ui:remove> is not took into account.
1.9.5.1.10. Component

143
Created by XMLmind

XSL-FO Converter.

The tag <ui:component> is identical to <ui:composition>, except that all the body of the tag is included in a JSF
component that we can use. To use it, we should use the attribute "bindings".
1.9.5.1.11. Fragment
The tag <ui:fragment> is identical to <ui:component> in its working, but, like the tag <ui:decorate>, the tags of
the calling page will be included in the final reply.
1.9.5.1.12. JSTL and Fonctions Tags
Facelets proposes an implementation of JSTL Core taglibs and of functions.
1.9.5.1.12.1. JSTL Core
To
use
the
tags
JSTL
Core,
"xmlns:c="http://java.sun.com/jstl/core""

we

should

declare

the

following

namespace:

Table 2.16. <c:if>


Attribute

Mandatory

Description

test

Yes

Expression to evaluate. If the


expression is true then the body of
the tag is took into account, else it is
ignored. An expression null is false.

var

No

Variable that must contains the result


of the test of the expression.

Example:
[CODE:xhtml]<c:if test="#{user.roles['admin']}">
</c:if>

Table 2.17. <c:forEach>


Attribute

Description

items

An expression that points to the Collection, the Map ou


the table to browse.

var

Contains the current element that we are browsing.

begin

Index from which to begin the iteration.

end

Index to which to end the iteration.

step

The value to add to the index at every iteration.

varStatus

Point to an object that contains the following


properties:

boolean first

boolean last

int begin

int end

int index

144
Created by XMLmind

XSL-FO Converter.

Attribute

Description

int step

Table 2.18. <c:set>


Attribute

Description

var

The variable that will contains the value of the


attribute "value".

value

The expression wich will determinate the value of the


variable. This expression will be reused at every time
the variable will be used. Ie. there is no copy of this
value in the variable designated by the attribute "var".

1.9.5.1.12.2. Functions
To
use
the
functions,
we
should
"xmlns:fn="http://java.sun.com/jsp/jstl/functions"".

declare

the

following

namespace:

1.9.6. Components Templating


1.9.6.1. Problem with JSF
Despite the simplicity of JSF, there are numerous cases where we are obliged to repeat code that is looking
pretty the same. This is the case for presentation code, as we have seen in the chapter " 1.3 View Templating ",
but the problems can also arise for personal components.
1.9.6.2. Facelets Solution
Thanks to its template system, Facelets allow to create a tag that we will use as a component. This tag will
generate all the code for different copies. The only thing that we will have to provide is the list of attributes that
can be changed between several copies of the code.
CaseComponent.xhtml:
[CODE: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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:c="http://java.sun.com/jstl/core"
xmlns:fn="http://java.sun.com/jsp/jstl/functions">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
<title></title>
</head>
<body>
<!-- Parameters:
- columnName:Name of the column
- sortMethod:Name of the method in the bean to sort the column
- bean:Bean that contains the sort method
- caseValue:Value of the case
-->
<ui:composition>
<h:column>
<f:facet name="header">
<h:panelGroup>
<!-- If this column is sortable, the name is a GUI link allowing to sort it -->
<c:if test="#{!empty sortMethod}">
<h:commandLink action="#{bean[sortMethod]}">
<h:outputText value="#{columnName}" />
</h:commandLink>
</c:if>

145
Created by XMLmind

XSL-FO Converter.

<!-- Else, we only display the name -->


<c:if test="#{empty sortMethod}">
<h:outputText value="#{columnName}" />
</c:if>
</h:panelGroup>
</f:facet>
<h:outputText value="#{caseValue}" />
</h:column>
</ui:composition>
</body>
</html>

1.9.6.3. TagFile
To use this component template with to a tag, we must add it in a declaration file. The file must have the
extension ".taglib.xml".
labo-sun.taglib.xml:
[CODE:xml]<?xml version="1.0"?>
<!DOCTYPE facelet-taglib PUBLIC
"-//Sun Microsystems, Inc.//DTD Facelet Taglib 1.0//EN"
"facelet-taglib_1_0.dtd">
<facelet-taglib>
<namespace>http://www.labo-sun.com/jsf</namespace>
<tag>
<tag-name>case</tag-name>
<source>CaseComponent.xhtml</source>
</tag>
</facelettaglib>

This declaration will allow to use our template with a tag of this kind:
[CODE:xhtml]<case columnName="" sortMethod="" caseValue="" bean="" />

The attributes of the tag are determined from the variables that are used in the template page. For Facelets to
load the file, we must add the following declaration in the file web.xml:
[CODE:xml]<context-param>
<param-name>facelets.LIBRARIES</param-name>
<param-value>/WEB-INF/facelets/tags/arcmind.taglib.xml</param-value>
</context-param>

Declaration:
[CODE:xml]<managed-bean>
<managed-bean-name>beanTable</managed-bean-name>
<managed-bean-class>com.labosun.facelets.BeanTable</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
[CODE:java]public class BeanTable {
private List<Person> persons;
private static Comparator<Person> personLastNameComparator = new Comparator<Person>() {
public int compare(Person o1, Person o2) {
return o1.getLastName().compareTo(o2.getLastName());
}
};
private static Comparator<Person> personFirstNameComparator = new Comparator<Person>() {
public int compare(Person o1, Person o2) {
return o1.getFirstName().compareTo(o2.getFirstName());
}
};
public BeanTable() {
persons = new ArrayList<Person>();
persons.add(new Person("Bob", "Gnoliac"));
persons.add(new Person("Thomas", "Anderson"));
persons.add(new Person("Raymond", "Smith"));
}
//Getter et setter

146
Created by XMLmind

XSL-FO Converter.

public void sortByFirstName() {


Collections.sort(getPersons(), personFirstNameComparator);
}
public void sortByLastName() {
Collections.sort(getPersons(), personLastNameComparator);
}
}

That's all, our tag is ready to be used. The declaration is done with namespaces like that:
[CODE: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://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:m="http://www.labo-sun.com/jsf">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF8"/>
<title>Test column template</title>
</head>
<body>
<h:form>
<h:dataTable value="#{beanTable.persons}" var="person" border="1" rules="all">
<m:case columnName="Last name" sortMethod="sortByLastName"
caseValue="#{person.lastName}" bean="#{beanTable}" />
<m:case columnName="First name" sortMethod="sortByFirstName"
caseValue="#{person.firstName}" bean="#{beanTable}" />
</h:dataTable>
</h:form>
</body>
</html>

Here is the final result:

Table 2.19.
Sort by Last Name

Sort by First Name

1.9.7. Parameters
Table 2.20.
Parameters

Description

facelets.LIBRARIES
List of paths to libraries of Facelets tags separated by
";". The paths are relative to the root of the applciation.
A library is loaded only when the page that use it
should be compiled.
Example:

/WEB-INF/facelets/my.taglib.xml;

/WEB-INF/facelets/car.taglib.xml;
facelets.DECORATORS

A list of classes (separated with ";" of the type


"com.sun.facelets.tag.TagDecorator" with a default
constructor. Those decorators will be loaded during the
147
Created by XMLmind

XSL-FO Converter.

Parameters

Description
first query will get to the view "FaceletViewHandler".
Example: com.sun.facelets.tag.jsf.html.HtmlDecorator

facelets.DEVELOPMENT

If true, then debugging informations will be displayed


on the Web page when there is an error. The default
value is false.

facelets.BUFFER_SIZE

The size of the buffer used by the ResponseWriter. Be


careful, a too small buffer size will no allow to display
a page in its entirety. By default, the value is 1, it
allows to not set any size limit.

facelets.REFRESH_PERIOD

Allow to define the minimum time interval that must


wait the compilator before to check if a page should be
recompiled (if there are any changes). The value 1
allow to prevent the compilator to check if there are
changes once the page is compiled. The default value
is 2.

facelets.RESOURCE_RESOLVER

Allow to specify a custom ResourceResolver. The


default
value
is:
com.sun.facelets.impl.DefaultResourceResolver

facelets.VIEW_MAPPINGS

A list of URLs (separated by ";") that will be managed


by Facelets. If nothing is precised, every requests will
be managed by Facelets. In the case where an URL is
not managed by Facelets, the parent default view (JSP)
is used. Be careful, if you specify URLs, the mapping
to the servler FacesServlet should be mapped for
several types of files.
Example: /faces/*;*.xhtml

1.10. Bibliography
JSF tags documentation:
JSF 1.1 : http://java.sun.com/j2ee/javaserverfaces/1.1/docs/tlddocs/index.html
JSF 1.2 : http://java.sun.com/j2ee/javaserverfaces/1.2/docs/tlddocs/index.html
JSF javadoc:
JSF 1.1 : http://java.sun.com/j2ee/javaserverfaces/1.1/docs/api/index.html
JSF 1.2 : http://java.sun.com/j2ee/javaserverfaces/1.2/docs/api/index.html
Sun

tutorial

for

J2EE

1.4

which

includes

tutorial

for

JSF

1.1:

tutorial

for

JSF

1.2:

http://java.sun.com/j2ee/1.4/docs/tutorial/doc/index.html
Sun

tutorial

for

JEE

5.0

which

includes

http://java.sun.com/javaee/5/docs/tutorial/doc/index.html
Facelets homepage: https://facelets.dev.java.net/
MyFaces homepage: http://myfaces.apache.org/index.html
Oracle

ADF

http://www.oracle.com/technology/products/jdev/htdocs/partners/addins/exchange/jsf/index.h
tml
148
Created by XMLmind

XSL-FO Converter.

Vous aimerez peut-être aussi