JSF 2.0 Features: An Extension

Exclusive offer: get 50% off this eBook here
JSF 2.0 Cookbook

JSF 2.0 Cookbook — Save 50%

Over 100 simple but incredibly effective recipes for taking control of your JSF applications

$26.99    $13.50
by Anghel Leonard | June 2010 | Java Open Source Web Development

In the article JSF 2.0 Features, by Anghel Leonard, author of the book JSF 2.0 Cookbook, we covered the following features of JSF 2.0:

  • JSF 2.0 annotations
  • The JSF 2.0 exception handling mechanism
  • Bookmarking JSF pages with PrettyFaces

In this article we will cover some more features of JSF 2.0, such as:

  • JSF declarative event handling
  • URLs based on specified navigation outcome
  • JSF view parameters
  • JSF 2 and navigation cases

(For more resources on JSF, see here.)

JSF declarative event handling

Starting with JSF 2.0 the event system has been really improved and the declarative event handling is exposed through a tag, f:event, and an annotation, @NamedEvent. In this recipe, you will see how to work with these two and how to subscribe to events like preRenderComponent, PostAddToView , and so on.

Getting ready

We developed this recipe with NetBeans 6.8, JSF 2.0, and GlassFish v3. The JSF 2.0 classes were obtained from the NetBeans JSF 2.0 bundled library.

How to do it...

Starting with the f:event tag, we can say that this is a simple tag that should be fitted in the right place and configured with its two simple attributes. Speaking of fitting it in the right place, you should know that f:event can be placed in any component that you want—for example we put it in an h:inputText component:

<h:inputText value="#{bean.number}">
<f:event type="preRenderComponent"
listener="#{bean.initNumber}" />
</h:inputText>
...

As you can see there are two attributes of the f:event tag , named type and listener. The value of the type attribute represents the name of the event for which to install a listener (in our example, we have used the preRenderComponent value—with other words, before the component is rendered). In the following table are the possible values, and the corresponding event type for which the listener action is registered.

Value for type attribute

Type of event sent to listener method

preRenderComponent

javax.faces.event.PreRenderComponentEvent

postAddToView

javax.faces.event.PostAddToViewEvent

preValidate

javax.faces.event.PreValidateEvent

postValidate

javax.faces.event.PostValidateEvent

The listener attribute's value represents a MethodExpression pointing to a method that will be called when the listener's processEvent method would have been called. In our example, that method is named initNumber and it can be seen in the following managed bean:

package beans;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class Bean {

private String number = "";

public Bean() {
}

public String getNumber() {
return number;
}

public void setNumber(String number) {
this.number = number;
}

public void initNumber(){
setNumber("2010");
}
}

While f:event works only with predefined events, the @NamedEvent provides support for exposing custom events. The application developer can make a custom event available to the page authors using the @NamedEvent annotation . This annotation can be placed on custom events to register them with the runtime, making them available to f:event. When the application starts, JSF scans for a set of annotations, including @NamedEvent. If it is found on a class, the following logic is applied to get the name/names for the event:

  1. Get the unqualified class name
  2. Cut off the trailing "Event", if present
  3. Convert the first character to lower-case
  4. Prepend the package name to the lower-cased name

The preceding four rules are ignored if the shortName attribute is specified. In this case JSF registers the event by that name.

URLs based on specified navigation outcome

One of the most requested features in JSF 2.0 was a nice and smooth mechanism for achieving bookmarkability of JSF pages. As you will see in this recipe, this mechanism is finally provided by JSF 2.0 and is a very robust and easy-to-use solution.

Getting ready

We have developed this recipe with NetBeans 6.8, JSF 2.0, and GlassFish v3. The JSF 2.0 classes were obtained from the NetBeans JSF 2.0 bundled library.

How to do it...

Now, let's get into the subject, and let's say that the JSF 2.0 bookmarkability mechanism is based on two new tags, named h:link and h:button. These tags will generate a URL based on the specified navigation outcome.

In JSF 2.0, we can make use of implicit navigation, therefore the outcome can be defined in the view or using common navigation rules.

OK, enough theory, let's see an example:

...
<h:link outcome="page2" value="HelloToYou">
<f:param name="helloparam" value="#{bean.hello}"/>
</h:link>
...

In the previous example, we assume no navigation rule, therefore the outcome attribute indicates a navigation to page2.xhtml (the FacesServlet is mapped to *.xhtml). The value attribute indicates text that will be rendered as a link in the page. The f:param will add a query parameter to the generated URL. The result of this component will be:

http://localhost:8080/ URLs_based_on_specified_navigation_outcome/ faces/page2.xhtml?helloparam=Adrian

The Adrian value comes from a simple managed bean:

package beans;

import javax.enterprise.context.RequestScoped;
import javax.faces.bean.ManagedBean;

@ManagedBean
@RequestScoped
public class Bean {

private String hello = "Adrian";

public Bean() {
}

public String getHello() {
return hello;
}

public void setHello(String hello) {
this.hello = hello;
}
}

You can bookmark this page at any moment and conserve the URL. The h:button works in the same manner except that it renders a button instead of a link.

How it works...

Before the user uses the component—clicks on the hyperlink—the current view ID and the specified outcome are used to find the target view ID. Afterwards, it is translated into a bookmarkable URL and used as the hyperlink's target. Note that this is true even if the user never activates the component.

The target view ID is placed in the attribute named outcome on the new bookmarkable component tags, h:link or/and h:button (those components inherit from a component class named UIOutcomeTarget). Notice that you are not targeting a view ID directly, but rather a navigation outcome, which may be interpreted as a view ID if the matching falls through to implicit navigation.

We consider that this is a good place and time to point out some methods of creating the query string parameters, therefore we present them in the order that they are processed:

  1. Implicit query string parameter
  2. View parameter (the <f:metadata> of the target view ID)
  3. Nested <f:param> in UIOutcomeTarget (such as, <h:link>)
  4. Nested <view-param> in the navigation case <redirect> element in facesconfig.xml
JSF 2.0 Cookbook Over 100 simple but incredibly effective recipes for taking control of your JSF applications
Published: June 2010
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

(For more resources on JSF, see here.)

JSF view parameters

Starting with JSF 2.0, a new set of parameters is available. This set is named view parameters. These parameters are specified as metadata to the page and can be included in the generated URLs as you will see in this recipe.

Getting ready

We have developed this recipe with NetBeans 6.8, JSF 2.0, and GlassFish v3. The JSF 2.0 classes were obtained from the NetBeans JSF 2.0 bundled library.

How to do it...

The official API documentation describes a view parameter as an entity represented by the javax.faces.component.UIViewParameter component class that acts as a declarative binding (using an EL value expression) between a request parameter and a model property.

A view parameter is commonly specified in the f:metdata tag using the f:viewParam tag (we say that the parameters are specified as metadata to the page), as in the following example (notice that this parameter is defined in page2.xhtml—we will navigate to this page from page1.xhtml):

...
<f:metadata>
<f:viewParam id="id" name="viewParam" value="#{bean.bye}"/>
</f:metadata>
...

Now, we will "exploit" this view parameter from a h:link hyperlink. This hyperlink is defined in page1.xhtml like this:

<h:link includeViewParams="true" outcome="page2.xhtml"
value="HelloToYouByeToHer">
<f:param name="helloparam" value="#{bean.hello}"/>
</h:link>
...

Notice that we have set the includeViewParams attribute to true on h:link (this is true for h:button also). This will have a great effect because the UIViewParameters will be a part of the generated URL. You also may use the include-view-params attribute on the redirect element of a navigation case set to true to obtain the same effect.

The result of this component is listed next—even if you never activate the component. Note that this URL can be bookmarked from the first moment: http://localhost:8080/JSF_ view_parameters/faces/page2.xhtml?helloparam=Adrian&viewParam=Mary.

The bean responsible for the values of helloparam and viewParam is:

package beans;

import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;

@ManagedBean
@SessionScoped
public class Bean {
private String hello = "Adrian";
private String bye = "Mary";

public Bean() {
}

public String getBye() {
return bye;
}

public void setBye(String bye) {
this.bye = bye;
}

public String getHello() {
return hello;
}

public void setHello(String hello) {
this.hello = hello;
}
}

Keep in mind that the view parameters that are included in the generated URL will be those of the view being navigated to.

Now, going deeper into the view parameters world, we notice that JSF 2.0 process the view parameters using the standard post-back processing lifecycle, which allows us to attach converters and validators to them. For example, we indicate that our view parameter is required as shown next:

...
<f:metadata>
<f:viewParam id="id" name="viewParam" value="#{bean.bye}"
required="true" requiredMessage="This parameter is a must!"/>
</f:metadata>
...

Or here is a more complex example, with a validator attached:

...
<f:metadata>
<f:viewParam id="id" name="id" value="#{bean.property}"
required="true" requiredMessage="..." converterMessage="..."
validatorMessage="...">
<f:validateLongRange minimum="1"/>
</f:viewParam>
</f:metadata>
...

Usage of f:metadata can be extended to Facelets templating features and view events, and is not specific only to view parameters. There's a lot more to view parameters than what was shown before.

How it works...

We can't say that the previous examples are self-explanatory, but we also can't explain here the secrets behind the scenes because we would then have a very large section. Anyway, what we can do is to make you aware that the view parameters provide information about how request parameters should be handled when a view is requested or linked to, which means that the view parameters are not rendered themselves. So, we say that they are part of the view's meta-model and described using metadata, f:metadata.

JSF 2 and navigation cases

A great feature of JSF 2.0 is focused on the navigation mechanism. Until JSF 2.0 the navigation cases mapped into faces-config.xml were fixed and once the application was deployed this file could not be altered, therefore its content was not flexible. That is no longer the case in JSF 2.0, because a new navigation handler interface, named ConfigurableNavigationhandler, has been introduced. It allows us to query and make live modifications to the registered NavigationCase objects. This is the subject of our last recipe in this article.

How to do it...

At JSF startup the navigation cases are extracted from the descriptor and registered with the ConfigurableNavigationHandler (of course, they are also put into NavigationCase objects). A NavigationCase object can be retrieved by the action expression signature and logical outcome under which it is registered:

...
NavigationCase navigationCase =
navigationHandler.getNavigationCase(facesContext, "#{...}", "...");
...

In addition, you can retrieve the complete navigation set as a Map<String, Set<NavigationCase>>. The keys are the <from-view-id> tag values (notice that you can use the extracted map to register your own navigation cases dynamically—once you can control a NavigationCase you can dynamically control flow):

...
Map<String, Set<NavigationCase>> ns =
navigationHandler.getNavigationCases();
...

To obtain a ConfigurableNavigationHandler object you need to apply a cast conversion as shown:

...
ConfigurableNavigationHandler configurableNavigationHandler =
(ConfigurableNavigationHandler)FacesContext.
getCurrentInstance().getApplication().getNavigationHandler();
...

How it works...

In principle, the new JSF 2.0 API allows us to have complete control over navigation cases. This feature allows us to dynamically control the application flow and once you get an instance of ConfigurableNavigationHandler you can define the navigation model or use it to generate bookmarkable URLs.

For a complete list of JSF 2.0 features, have a look at Andy Schwartz's Weblog at http://andyschwartz.wordpress.com/2009/07/31/whats-new-in-jsf-2/ or the Javabeat classification available at http://www.javabeat.net/tips/116-newfeatures-in-jsf-20.html.

Summary

This article presented some more JSF 2.0 features, such as declarative event handling, URLs based on specified navigation outcome, JSF view parameters, JSF 2.0, and navigation cases.


Further resources on this subject:


JSF 2.0 Cookbook Over 100 simple but incredibly effective recipes for taking control of your JSF applications
Published: June 2010
eBook Price: $26.99
Book Price: $44.99
See more
Select your format and quantity:

About the Author :


Anghel Leonard

Anghel Leonard is a senior Java developer with more than 13 years of experience in Java SE, Java EE, and related frameworks. He has written and published more than 50 articles about Java technologies and more than 500 tips and tricks for many programming dedicated websites. In addition, he wrote two books about XML and Java (one for beginners and one for advanced developers) for Albastra, a Romanian publisher, three books for Packt: Jboss Tools 3 Developer Guide, JSF 2.0 Cookbook, and JSF 2.0 Cookbook LITE, and two books for APress: Pro Java 7 NIO 2 and Pro Hibernate and MongoDB. Currently, he's developing web applications using the latest Java technologies on the market (EJB 3.0, CDI, Spring, JSF, Struts, Hibernate, and so on). For the past two years, he has focused on developing rich Internet applications for geographic information systems.

Books From Packt

Amazon SimpleDB Developer Guide
Amazon SimpleDB Developer Guide

GlassFish Security
GlassFish Security

Oracle JRockit: The Definitive Guide
Oracle JRockit: The Definitive Guide

NHibernate 2 Beginner's Guide
NHibernate 2 Beginner's Guide

Moodle 1.9 for Design and Technology
Moodle 1.9 for Design and Technology

Zabbix 1.8 Network Monitoring
Zabbix 1.8 Network Monitoring

Oracle Application Express 3.2 – The Essentials and More
Oracle Application Express 3.2 – The Essentials and More

Django 1.1 Testing and Debugging
Django 1.1 Testing and Debugging

Your rating: None Average: 4 (1 vote)
ConfigurableNavigationhandler is not an interface by
Per the Javadocs ConfigurableNavigationhandler is not an interface public abstract class ConfigurableNavigationHandler extends NavigationHandler How do you get access to ConfigurableNavigationHandler? thanks
Thanks to the author for the by
Thanks to the author for the informative article!!!

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
N
Z
f
D
9
X
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software