Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases now! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Mastering JavaServer Faces 2.2
Mastering JavaServer Faces 2.2

Mastering JavaServer Faces 2.2: Master the art of implementing user interfaces with JSF 2.2

eBook
€27.98 €39.99
Paperback
€49.99
Subscription
Free Trial
Renews at €18.99p/m

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Table of content icon View table of contents Preview book icon Preview Book

Mastering JavaServer Faces 2.2

Chapter 1. Dynamic Access to JSF Application Data through Expression Language (EL 3.0)

Java Expression Language (EL) is a compact and powerful mechanism that enables dynamic communication in JSP and JSF-based applications (including development frameworks based on JSF such as PrimeFaces, ICEfaces, and RichFaces); we embed expressions in the presentation layer to communicate with the application logic layer. EL provides bidirectional communication, which means that we can expose application logic data to the user, but we also can submit user data to be processes. Generically speaking, EL can be used to populate HTTP requests with user data, to extract and expose data from HTTP responses, to update HTML DOM, to conditionally process data, and much more.

Note

Commonly, EL expressions will be present in JSP and JSF pages, but they can also appear outside, in faces-config.xml, for example.

In this chapter, you will see how to use EL in web pages to communicate with managed beans, which is the most common case in JSF applications. We will cover the following topics:

  • EL syntax, operators, and reserved words
  • EL immediate and deferred evaluation
  • EL value and method expressions
  • The conditional text in JSF
  • Write a custom EL resolver

EL syntax

In this section, you can see an overview of the main aspects of EL 2.2 and 3.0 syntax. EL supports a handful of operators and reserved words. Each of these are quickly described in the following section (more details are in the EL specification document (http://download.oracle.com/otndocs/jcp/el-3_0-fr-eval-spec/index.html)).

EL operators

EL supports the following categories of operators—arithmetic, relational, logical, conditional, empty and added starting with EL 3.0, string concatenation, assignment and semicolon operators:

Textuals

Description

Symbols

A + B

Addition

+

A - B

Subtraction

-

A * B

Multiplication

*

A {div, /} B

Arithmetic operator division

/, div

A {mod, %} B

Arithmetic operator modulo

%, mod

A {and, &&} B

Logical AND

&&, and

A {or, ||} B

Logical OR

||, or

{not, !} A

Logical opposite

!, not

A {lt, <} B

Relational less than

<, lt

A {gt, >} B

Relational greater than

>, gt

A {le, <=} B

Relational less than or equal to

<=, le

A {ge, >=} B

Relational greater than or equal to

>=, ge

A {eq, ==} B

Equal to

==, eq

A {ne, !=} B

Not equal to

!=, ne

A = B

Assignment (EL 3.0)

=

A ; B

Semicolon (EL 3.0)

;

A += B

String concatenation (EL 3.0)

+=

A -> B

Lambda expression (EL 3.0)

->

empty A

Determine whether a value is null or empty

 

A ? B : C

Evaluates B or C, depending on the result of the evaluation of A. Known as the ternary operator.

?:

 

Used when writing EL expressions

.

 

Used when writing EL expressions

[]

EL precedence of operators

Conforming to EL specification, the precedence of operators from the highest to lowest, left to right is as follows:

  • [].
  • () (used to change the precedence of operators)
  • - (unary) not ! empty
  • * / div % mod
  • + - (binary)
  • +=
  • < > <= >= lt gt le ge
  • == != eq ne
  • && and
  • || or
  • ? :
  • -> (lambda expression)
  • =
  • ;

EL reserved words

EL defines the following reserved words:

  • and, or, not, eq, ne, lt, gt, le, ge, true (Boolean literal), false (Boolean literal), null, instanceof (a Java keyword to do a class comparison between objects), empty, div, and mod

EL immediate and deferred evaluation

EL evaluates expressions as immediate or deferred.

Immediate evaluation returns the result as soon as the page is first rendered. These kinds of expressions are read-only value expressions and they can be present only in tags that accept runtime expressions. They are easy to recognize after the ${} notation. Usually, they are used for arithmetic and logical operations in JSP pages.

Deferred evaluation can return the result at different phases of a page's life cycle depending on the technology that is using the expression. JSF can evaluate the expression at different phases of the life cycle (for example, during the rendering and postback phase), depending on how the expression is being used in the page. These kind of expressions can be value and method expressions, and they are marked by the #{} notation.

Note

In Facelets, ${} and #{} act the same.

EL value expressions

Value expressions are probably used the most, and they refer to objects and their properties and attributes. Such expressions are dynamically used to evaluate results or set bean properties at runtime. Through value expressions, you can easily access JavaBeans components, collections, and Java SE enumerated types. Moreover, EL provides a set of implicit objects that can be used to get attributes from different scopes and parameter values. Furthermore, you will see how EL deals with each of these objects.

Note

Value expressions that can read data, but cannot write it are known as rvalue (${} expressions are always rvalue), while those that can read and write data are known as lvalue (#{} expressions can be rvalue and/or lvalue).

Referencing a managed bean

Referencing a managed bean is not exactly a useful example, but it is a good point to start. Most commonly, your managed bean will look like the following code (in this case, the bean's class name is PlayersBean):

@ManagedBean
//some scope
public class PlayersBean{
...
}

Or, in the CDI version, your managed bean will be as follows:

@Named
//some scope
public class PlayersBean{
...
}

Or, with an explicit name, your managed bean will be as follows:

@ManagedBean(name = "myPlayersBean")
//some scope
public class PlayersBean{
...
}

@Named(value = "myPlayersBean")
//some scope
public class PlayersBean{
...
}

Now, for the first two examples, EL refers to the PlayersBean managed bean, like this—the name is obtained from taking the unqualified class name portion of the fully qualified class name and converting the first character to lowercase as follows:

#{playersBean}

In addition, for the next two examples, EL uses the explicit name as follows:

#{myPlayersBean}

Note

You should use CDI beans whenever possible since they are more flexible than JSF managed beans, and because annotations from javax.faces.bean will be deprecated in a future JSF version. Therefore, the CDI ones are recommended.

When the referenced managed bean cannot be found in any scope, a null value will be returned.

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

Referencing a managed bean's properties

As is commonly known, managed beans usually contain private fields, which are accessible through getter and setter methods as bean properties, and some public methods that exploits these properties to serve different logic tasks.

EL expressions that can access these properties contain the dot or square brackets notation, []. For example, let's suppose that the PlayersBean managed bean contains two fields defined like the following lines:

private String playerName = "Rafael";
private String playerSurname = "Nadal";

EL can access these fields through their getter methods; therefore, you need to define them as shown in the following code:

public String getPlayerName() {
  return playerName;
}
public String getPlayerSurname() {
  return playerSurname;
}

Now, an expression that accesses the playerName property can use the dot notation (.) to refer it, as shown in the following line of code:

#{playersBean.playerName}

Alternatively, this expression can use the square brackets notation, [], as shown in the following line of code:

#{playersBean['playerName']}

Note

JSF evaluates this expression from left to right. First, it searches for playersBean in all available scopes (such as request, session, and application). Then, the bean is instantiated and the getPlayerName/getPlayerSurname getter methods are called (in the case of Boolean properties, the getter method will be named as isXXX).When you are using the [] notation, you can use simple or double quotes. Just remember to alternate them correctly in cases like the following quotations.

An incorrect quotation (you cannot use double quotes inside double quotes) is:

<h:outputText value="#{playersBean["playerName"]}"/>

An incorrect quotation (you cannot use simple quotes inside simple quotes) is:

<h:outputText value='#{playersBean['playerName']}'/>

A correct quotation (you can use simple quotes in double quotes) is:

<h:outputText value="#{playersBean['playerName']}"/>

A correct quotation (you can use double quotes in simple quotes) is:

<h:outputText value='#{playersBean["playerName"]}'/>

Referencing a managed bean's nested properties

Usually, managed beans use nested properties. Such properties can be accessed by EL using the . and [] notations multiple times in the same expression.

For example, the PlayersBean managed bean may represent general data about tennis players, such as name, surname, titles, and finals. More detailed information, such as birthday, birthplace, height, and weight can be represented through a different class named PlayersDetails. Now, the PlayersBean managed bean contains a field of type PlayersDetails, which means that birthday, birthplace, and so on become nested properties of PlayersBean. Speaking in code lines, the relevant part of the PlayersDetails class is as follows:

public class PlayerDetails {

  private Date birthday;
  private String birthplace;
  ...

  public Date getBirthday() {
    return birthday;
  }

  public String getBirthplace() {
    return birthplace;
  }
  ...
}

The managed bean of the PlayersBean class is as follows:

@Named
public class PlayersBean{

  private String playerName = "Rafael";
  private String playerSurname = "Nadal";
  private PlayerDetails playerDetails;

  public String getPlayerName() {
    return playerName;
  }

  public String getPlayerSurname() {
    return playerSurname;
  }

  public PlayerDetails getPlayerDetails() {
    return playerDetails;
  }
  ...
}

You already know how to call the playerName and playerSurname properties using the . and [] notations. Next, you can use the same notations to access the birthday and birthplace nested properties, as shown in the following code:

#{playersBean.playerDetails.birthday}
#{playersBean.playerDetails.birthplace}

#{playersBean['playerDetails']['birthday']}
#{playersBean['playerDetails']['birthplace']}

Or, you can use both notations in the same expressions, as shown in the following code:

#{playersBean.playerDetails['birthday']}
#{playersBean.playerDetails['birthplace']}

#{playersBean['playerDetails'].birthday}
#{playersBean['playerDetails'].birthplace}

Of course, the PlayerDetails class can contain its own nested properties and so. In this case, just use the . and [] notations to get deeper in the hierarchy of objects until you reach the desired property.

In the preceding expressions, JSF search for playersBean in all the available scopes (request, session, application, and so on) and obtain an instance of it. Afterwards, it calls the getPlayerDetails method and the getBirthday method on result of the getPlayerDetails method (and the same for the birthplace property).

Referencing Java SE enumerated types

EL can access Java SE enumerated types using a String literal. For example, let's have an enumerated type defined in PlayersBean, as shown in the following code:

public enum Plays {
  Left, Right
};

private Plays play;
...
play = Plays.Left;//initialization can be done in constructor
...
public Plays getPlay() {
  return play;
}
...

You can easily output the play value as shown in the following line of code:

#{playersBean.play}

To refer to the Plays constant, Plays.Left, with an expression, use the String literal Left (or Right for Plays.Right), for example, you can test whether play is Left or Right, as shown in the following code:

#{playersBean.play == 'Left'} //return true
#{playersBean.play == 'Right'}//return false

Referencing collections

Collection items (arrays, lists, maps, sets, and so on) can be accessed from EL expressions by specifying a literal value that can be converted to an integer or the [] notation with an integer and without quotes.

For example, let's suppose that the PlayersBean managed bean contains an array named titles_2013 that keeps the titles won by a player in 2013. The array is defined as shown in the following code:

private String[] titles_2013 = {"Sao Paulo", "Acapulco", "ATP World Tour Masters 1000 Indian Wells", "Barcelona", ...};
...
public String[] getTitles_2013() {
  return titles_2013;
}   

Now, you can access the first title from the array by specifying its position in array, which is 0:

#{playersBean.titles_2013[0]}

This is equivalent in Java to getting or setting the value for titles_2013[0].

However, sometimes you need to iterate over the array instead of accessing a specific item. This can be easily accomplished with the c:forEach JSTL tag (http://www.oracle.com/technetwork/java/index-jsp-135995.html). The following code snippet iterates over the titles_2013 array and outputs each item (this is a pretty uncommon usage, so do not try it in production):

<c:forEach begin="0" 
  end="${fn:length(playersBean.titles_2013)-1}" 
  var="i">
  #{playersBean.titles_2013[i]},
</c:forEach>

You can simplify it as shown in the following code:

<c:forEach var="title" items="#{playersBean.titles_2013}">
  <i>#{title}</i>,
</c:forEach>

You can also use the <ui:repeat> tag as shown in the following code:

<ui:repeat var="title" value="#{playersBean.titles_2013}">
  <i>#{title}</i>,
</ui:repeat>

This tag is detailed in Chapter 12, Facelets Templating, in the Iterating with <ui:repeat> section.

You can use the same approach for every List. For example, in the case of List, the expression #{playersBean.titles_2013[0]} is equivalent in Java to titles_2013.get(0) and titles_2013.set(0, some_value).

In the case of collections of type key-value (for example, Map), the EL expressions obtain items by key. For example, let's add a Map in PlayersBean that stores some match facts of a player. It can be defined as shown in the following code:

private Map<String, String> matchfacts = new HashMap<>();
...
matchfacts.put("Aces", "12");
matchfacts.put("Double Faults", "2");
matchfacts.put("1st Serve", "70%");
...

public Map<String, String> getMatchfacts() {
  return matchfacts;
}

Now, an EL expression that accesses the item with the key Aces can be written like the following line of code:

#{playersBean.matchfacts.Aces}

Note

Notice that this approach is not supported on arrays or lists. For example, #{playersBean.titles_2013.0} is not correct.

When the key is not an acceptable variable name (for example, Double Faults), you need to use brackets and quotes, as shown in the following code:

#{playersBean.matchfacts["Double Faults"]}

EL implicit objects

JSF provides several objects related to the current request and environment. EL exposes these objects (known as implicit objects) that can be accessed at runtime in a Facelet, servlets, or backing bean—these objects are accessible through value expressions and are managed by the container. For each expression, EL first checks if the value of the base is one of these implicit objects, and, if it is not, then it will check beans in progressively wider scopes (from request to view, and finally to application scope).

Note

In EL, the part of the expression before the dot or the square bracket is named base and it usually indicates where the bean instances should be located. The part after the first dot, or the square bracket, is called a property and is recursively cracked in smaller parts, which represents the bean's properties to get from the base.

You can see a short overview of these objects in the following table:

Implicit object EL

Type

Description

#{application}

ServletContext or PortletContext

This is an instance of ServletContext or PortletContext.

#{facesContext}

FacesContext

This is an instance of FacesContext.

#{initParam}

Map

This is the context initialization parameter map returned by getInitParameterMap.

#{session}

HttpSession or PortletSession

This is an instance of HttpSession or PortletSession.

#{view}

UIViewRoot

This is the current UIViewRoot (the root of the UIComponent tree).

#{component}

UIComponent

This is the current UIComponent.

#{cc}

UIComponent

This is the composite component currently being processed.

#{request}

ServletRequest or PortletRequest

This is an instance of ServletRequest or PortletRequest.

#{applicationScope}

Map

This is a map to store application-scoped data returned by getApplicationMap.

#{sessionScope}

Map

This is a map to store session-scoped data returned by getSessionMap.

#{viewScope}

Map

This is a map to store current view scoped data returned by getViewMap.

#{requestScope}

Map

This is a map to store request-scoped data returned by getRequestMap.

#{flowScope}

Map

This is a map to store flow-scoped data returned by facesContext.getApplication().getFlowHandler().getCurrentFlowScope().

#{flash}

Map

This is a map that contains values present only on the "next" request.

#{param}

Map

This is a map view of all the query parameters for this request. It is returned by getRequestParameterMap.

#{paramValues}

Map

This is the request parameter value map returned by getRequestParameterValuesMap.

#{header}

Map

This is a map view of all the HTTP headers for this request returned by getRequestHeaderMap.

#{headerValue}

Map

This is the request header values map returned by getRequestHeaderValuesMap. Each value in the map is an array of strings that contains all the values for that key.

#{cookie}

Map

This is a map view of values in the HTTP Set-Cookie header returned by getRequestCookieMap.

#{resource}

Resource

This is a JSF resource identifier to a concrete resource URL.

EL method expressions

With EL expressions, we can call arbitrary static and public methods that live on the server side in managed beans. Such expressions are usually present in tag's attributes (that is, inside an action or actionListener attribute) and must use the deferred evaluation syntax since a method can be called during different phases of the life cycle. Commonly, methods are called to respond with actions to different kinds of events and for autopages navigation.

Let's see some examples of calling bean methods using EL (all methods were defined in the PlayersBean managed bean):

  • Calling the vamosRafa_1 void bean method with no arguments, as shown in the following code:
    public void vamosRafa_1(){
      System.out.println("Vamos Rafa!");
    }
    
    #{playersBean.vamosRafa_1()}
  • Calling the vamosRafa_2 bean method with no arguments. It returns a string, as shown in the following code:
    public String vamosRafa_2() {
      return "Vamos Rafa!";
    }
    
    #{playersBean.vamosRafa_2()}

    The returned string, Vamos Rafa!, can be displayed on the web page or used for other purposes. In other words, the expression will be evaluated to this string.

  • Calling the vamosRafa_3 bean method with one argument. It returns void, as shown in the following code:
    public void vamosRafa_3(String text) {
      System.out.println(text);
    }
    
    #{playersBean.vamosRafa_3('Vamos Rafa!')}

    Notice that the String arguments are passed by using quotes.

    Note

    The String constants are passed between simple or double quotes!

  • Calling the vamosRafa_4 bean method with two arguments. It returns a string, as shown in the following code:
    public String vamosRafa_4(String name, String surname) {    
      return "Vamos " + name + " " + surname + "!";
    }
    
    #{playersBean.vamosRafa_4(playersBean.playerName, playersBean.playerSurname)}

    The expression will be evaluated to the string, Vamos Rafael Nadal!.

  • Calling the vamosRafa_5 bean method for autonavigation. First, define the method in the managed bean to return a view (outcome) name (vamos is the view name for the vamos.xhtml file), as shown in the following code:
    public String vamosRafa_5(){
     return "vamos";
    }

Furthermore, extract the view name in the action attribute of any JSF UI component as shown in the following code:

<h:form>  
  <h:commandButton action="#{playersBean.vamosRafa_5()}" value="Vamos ..." />
</h:form>

Now, when the button labeled Vamos... is clicked, JSF will resolve the view name, vamos, to the vamos.xhtml file. Moreover, JSF will look for the vamos.xhtml file in the current directory and will navigate to it. Commonly, these navigation methods are used for conditional navigation between JSF pages.

Note

We have used parentheses to call a method, even when the method doesn't contain arguments. A special case is represented by the methods that contain an ActionEvent argument. These methods should be called without parentheses, except in the case when you override the ActionEvent argument altogether by passing and specifying custom argument(s).

EL expressions can also be used inside JavaScript function calls. For example, when you want to pass bean properties to a JavaScript function, you need to place them between quotes, as shown in the following code:

<h:form>
  <h:commandButton type="button" value="Click Me!" onclick="infoJS('#{playersBean.playerName}', '#{playersBean.playerSurname}')"/>
</h:form>

The JavaScript function for this is shown in the following code:

<script type="text/javascript">
  function infoJS(name, surname) {
    alert("Name: " + name + " Surname: " + surname);
  }
</script>

The conditional text in JSF

When you need to output the conditional text (without the HTML content), you can use the EL ternary operator, which has the following syntax:

boolean_test ? result_for_true : result_for_false

For example, you can use this operator to select between two CSS classes, as shown in the following code:

.red { color:#cc0000; } 
.blue { color: #0000cc; }

Now, you want to conditionally output a red or a blue text, as shown in the following code:

<h:outputText styleClass="#{playersBean.play == 'Left' ? 'red': 'blue'}" value="#{playersBean.play}"/>

So, if the value of play is Left, the text will be displayed using the red CSS class, and if it is not Left, then the blue class will be used.

Note

Keep in mind that the HTML content is not recommended (for security reasons do not use escape="false"), and the else part of the condition cannot be omitted.

For better understanding, let's look at another example. Remember that you have iterated over the titles_2013 array and output each item as shown in the following code:

<c:forEach var="title" items="#{playersBean.titles_2013}">
  <i>#{title}</i>,
</c:forEach>

Well, the output of this code will be something like the following screenshot:

The conditional text in JSF

Everything looks fine except the last comma, which should not appear since the US Open term is the last item to display. You can easily fix this issue with the EL ternary operator, as shown in the following code:

<c:forEach var="title" items="#{playersBean.titles_2013}" varStatus="v">
  <i>#{title}</i>
  #{v.last ? '':','}
</c:forEach>

Sometimes you just need to show or hide text based on a condition. For this, you can place a Boolean expression as the value of the rendered attribute (all JSF UI components have this attribute). For example, the following line of code will output a player's Facebook address only if such an address exists:

<h:outputText value="Facebook address: #{playersBean.facebook}" rendered="#{!empty playersBean.facebook}" />

Another common situation is to display or hide non-HTML text using two buttons of type "Show something..." and "Hide something...". For example, you can have a button labeled Show Career Prize Money and one labeled Hide Career Prize Money. Obviously, you want to display the career prize money when the first button is clicked and to hide the career prize money when the second button is clicked. For this, you can use the rendered attribute, as shown in the following code:

<h:form id="prizeFormId">
  <h:commandButton value="Show Career Prize Money">
  <f:ajax render="rnprizeid"  listener="#{playersBean.showPrizeMoney()}"/>
  </h:commandButton>
  <h:panelGrid id="rnprizeid">
    <h:outputText value="#{playersBean.prize}" rendered="#{playersBean.show_prize}">
      <f:convertNumber type="currency" currencySymbol="$" />
    </h:outputText>            
  </h:panelGrid>
  <h:commandButton value="Hide Career Prize Money">
    <f:ajax render="rnprizeid" 
            listener="#{playersBean.hidePrizeMoney()}"/>
  </h:commandButton>
</h:form>

Both the buttons use AJAX mechanism and an EL method expression to call the showPrizeMoney and hidePrizeMoney methods. These methods just modify the value of a boolean property, named show_prize, as shown in the following code:

private boolean show_prize = false;
...
public boolean isShow_prize() {
  return show_prize;
}
...
public void showPrizeMoney(){
  this.show_prize = true;
}
    
public void hidePrizeMoney(){
  this.show_prize = false;
}

When the request is complete, JSF will re-render the panel grid component with the ID rnprizeid; this was indicated in the render attribute of the f:ajax tag. As you can see, the re-rendered component is a panel that contains a simple h:outputText tag that outputs the prize property depending on the Boolean value of the EL expression present in the rendered attribute, as shown in the following code:

private int prize = 60941937;
...
public int getPrize() {
  return prize;
}

Showing and hiding text can be useful, but not enough. Usually, we need to show or hide the HTML content. For example, you may need to show or hide a picture:

<img src="resources/images/babolat.jpg" width="290" height="174"/>

This task can be easily accomplished by nesting the HTML code inside the Facelets ui:fragment tag, which supports the rendered attribute, as shown in the following code:

<ui:fragment rendered="#{playersBean.show_racquet}">
  <img src="#{resource['images:babolat.jpg']}" width="290" height="174"/>
</ui:fragment>

As you can see, the EL expression of the rendered attribute indicates a boolean property of the PlayersBean managed bean, as shown in the following code:

private boolean show_racquet = false;
...
public boolean isShow_racquet() {
  return show_racquet;
}

Now, you can let the user decide when to show or hide the image. You can easily adapt the preceding example, with two buttons labeled Show Image and Hide Image, or more elegant, you can use a checkbox, as shown in the following code:

...
<h:form>
  <h:selectBooleanCheckbox label="Show Image"valueChangeListener="#{playersBean.showHideRacquetPicture}">
    <f:ajax render="racquetId"/>
  </h:selectBooleanCheckbox>        
  <h:panelGroup id="racquetId">
    <ui:fragment rendered="#{playersBean.show_racquet}">
    <img src="resources/images/babolat.jpg" width="290" height="174"/>
  </ui:fragment>    
  </h:panelGroup>
</h:form>
...

The showHideRacquetPicture method sets the value of the show_racquet property to true or false, depending on the checkbox status. After this method is executed, JSF will re-render the content of the ui:fragment tag—this is accomplished via the HTML content rendered by the <h:panelGroup> tag, because the <ui:fragment> tag doesn't render the HTML content; therefore, it cannot be referenced by the ID. The following is the code for the showHideRacquetPicture method:

public void showHideRacquetPicture(ValueChangeEvent e){
  if(e.getNewValue() == Boolean.TRUE){
     this.show_racquet=true;
  } else {
     this.show_racquet=false;
  }
}

So, we can conclude that the rendered attribute can be used to conditionally output the HTML/non-HTML content. The user interaction and internal conditions can be used to play with this attribute value.

The complete application is named ch1_1.

Writing a custom EL resolver

EL flexibility can be tested by extending it with custom implicit variables, properties, and method calls. This is possible if we extend the VariableResolver or PropertyResolver class, or even better, the ELResolver class that give us flexibility to reuse the same implementation for different tasks. The following are three simple steps to add custom implicit variables:

  1. Create your own class that extends the ELResolver class.
  2. Implement the inherited abstract methods.
  3. Add the ELResolver class in faces-config.xml.

Next, you will see how to add a custom implicit variable by extending EL based on these steps. In this example, you want to retrieve a collection that contains the ATP singles rankings using EL directly in your JSF page. The variable name used to access the collection will be atp.

First, you need to create a class that extends the javax.el.ELResolver class. This is very simple. The code for the ATPVarResolver class is as follows:

public class ATPVarResolver extends ELResolver {

  private static final Logger logger = Logger.getLogger(ATPVarResolver.class.getName());
  private static final String PLAYERS = "atp";
  private final Class<?> CONTENT = List.class;
...
}

Second, you need to implement six abstract methods:

  • getValue: This method is defined in the following manner:
    public abstract Object getValue(ELContext context, Object base, Object property)

    This is the most important method of an ELResolver class. In the implementation of the getValue method, you will return the ATP items if the property requested is named atp. Therefore, the implementation will be as follows:

    @Override
    public Object getValue(ELContext ctx, Object base, Object property) {
    
    logger.log(Level.INFO, "Get Value property : {0}", property);
    
      if ((base == null) && property.equals(PLAYERS)) {
        logger.log(Level.INFO, "Found request {0}", base);    
        ctx.setPropertyResolved(true);          
        List<String> values = ATPSinglesRankings.getSinglesRankings();
        return values;
        }
      return null;
    }
  • getType: This method is defined in the following manner:
    public abstract Class<?> getType(ELContext context, Object base,Object property)

    This method identifies the most general acceptable type for our property. The scope of this method is to determine if a call of the setValue method is safe without causing a ClassCastException to be thrown. Since we return a collection, we can say that the general acceptable type is List. The implementation of the getType method is as follows:

    @Override
    public Class<?> getType(ELContext ctx, Object base, Object property) {
    
      if (base != null) {
        return null;
      }
    
      if (property == null) {
        String message = MessageUtils.getExceptionMessageString(MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "property");
        throw new PropertyNotFoundException(message);
      }
    
      if ((base == null) && property.equals(PLAYERS)) {
        ctx.setPropertyResolved(true);
        return CONTENT;
      }
      return null; 
    }
  • setValue: This method is defined in the following manner:
    public abstract void setValue(ELContext context, Object base, Object property, Object value)

    This method tries to set the value for a given property and base. For read-only variables, such as atp, you need to throw an exception of type PropertyNotWritableException. The implementation of the setValue method is as follows:

    @Override
    public void setValue(ELContext ctx, Object base, Object property, Object value) {
    
      if (base != null) {
        return;
      }
    
      ctx.setPropertyResolved(false);
      if (property == null) {
        String message = MessageUtils.getExceptionMessageString(MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "property");
        throw new PropertyNotFoundException(message);
      }
    
      if (PLAYERS.equals(property)) {
        throw new PropertyNotWritableException((String) property);
      }
    }
  • isReadOnly: This method is defined in the following manner:
    public abstract boolean isReadOnly(ELContext context, Object base, Object property)

    This method returns true if the variable is read-only and false otherwise. Since the atp variable is read-only, the implementation is obvious. This method is directly related to the setValue method, meaning that it signals whether it is safe or not to call the setValue method without getting PropertyNotWritableException as a response. The implementation of the isReadOnly method is as follows:

    @Override
    public boolean isReadOnly(ELContext ctx, Object base, Object property) {
      return true;
    }
  • getFeatureDescriptors: This method is defined in the following manner:
    public abstract Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext context, Object base

    This method returns a set of information about the variables or properties that can be resolved (commonly it is used by a design time tool (for example, JDeveloper has such a tool) to allow code completion of expressions). In this case, you can return null. The implementation of the getFeatureDescriptors method is as follows:

    @Override
    public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext ctx, Object base) {
      return null;
    }
  • getCommonPropertyType: This method is defined in the following manner:
    public abstract Class<?> getCommonPropertyType(ELContext context, Object base)

    This method returns the most general type that this resolver accepts. The implementation of the getCommonPropertyType method is as follows:

    @Override
    public Class<?> getCommonPropertyType(ELContext ctx, Object base) {
      if (base != null) {
        return null;
      }
      return String.class;
    }

Note

How do you know if the ELResolver class acts as a VariableResolver class (these two classes are deprecated in JSF 2.2) or as a PropertyResolver class? The answer lies in the first part of the expression (known as the base argument), which in our case is null (the base is before the first dot or the square bracket, while property is after this dot or the square bracket). When the base is null, the ELresolver class acts as a VariableResolver class; otherwise, it acts as a PropertyResolver class.

The getSinglesRankings method (that populates the collection) is called from the getValue method, and is defined in the following ATPSinglesRankings class:

public class ATPSinglesRankings {
    
  public static List<String> getSinglesRankings(){
       
    List<String> atp_ranking= new ArrayList<>();
        
    atp_ranking.add("1 Nadal, Rafael (ESP)");
    ...              
        
    return atp_ranking;
  }
}

Third, you register the custom ELResolver class in faces-config.xml using the <el-resolver> tag and specifying the fully qualified name of the corresponding class. In other words, you add the ELResolver class in the chain of responsibility, which represents the pattern used by JSF to deal with ELResolvers:

<application>
  <el-resolver>book.beans.ATPVarResolver</el-resolver>
</application>

Note

Each time an expression needs to be resolved, JSF will call the default expression language resolver implementation. Each value expression is evaluated behind the scenes by the getValue method. When the <el-resolver> tag is present, the custom resolver is added in the chain of responsibility. The EL implementation manages a chain of resolver instances for different types of expression elements. For each part of an expression, EL will traverse the chain until it finds a resolver capable to resolve that part. The resolver capable of dealing with that part will pass true to the setPropertyResolved method; this method acts as a flag at the ELContext level.

Furthermore, EL implementation checks, after each resolver call, the value of this flag via the getPropertyResolved method. When the flag is true, EL implementation will repeat the process for the next part of the expression.

Done! Next, you can simply output the collection items in a data table, as shown in the following code:

<h:dataTable id="atpTableId" value="#{atp}" var="t">
  <h:column>
    #{t}
  </h:column>
</h:dataTable>

Well, so far so good! Now, our custom EL resolver returns the plain list of ATP rankings. But, what can we do if we need the list items in the reverse order, or to have the items in uppercase, or to obtain a random list? The answer could consist in adapting the preceding EL resolver to this situation.

First, you need to modify the getValue method. At this moment, it returns List, but you need to obtain an instance of the ATPSinglesRankings class. Therefore, modify it as shown in the following code:

public Object getValue(ELContext ctx, Object base, Object property) {

  if ((base == null) && property.equals(PLAYERS)) {
    ctx.setPropertyResolved(true);
    return new ATPSinglesRankings();
  }
  return null;
}

Moreover, you need to redefine the CONTENT constant accordingly as shown in the following line of code:

private final Class<?> CONTENT = ATPSinglesRankings.class;

Next, the ATPSinglesRankings class can contain a method for each case, as shown in the following code:

public class ATPSinglesRankings {
    
  public List<String> getSinglesRankings(){
       
    List<String> atp_ranking= new ArrayList<>();
        
    atp_ranking.add("1 Nadal, Rafael (ESP)");
    ...             
        
    return atp_ranking;
  }
    
  public List<String> getSinglesRankingsReversed(){
       
    List<String> atp_ranking= new ArrayList<>();
                
    atp_ranking.add("5 Del Potro, Juan Martin (ARG)");
    atp_ranking.add("4 Murray, Andy (GBR)");        
    ...  
                
    return atp_ranking;
  }
    
  public List<String> getSinglesRankingsUpperCase(){
       
    List<String> atp_ranking= new ArrayList<>();
                
    atp_ranking.add("5 Del Potro, Juan Martin (ARG)".toUpperCase());                        
    atp_ranking.add("4 Murray, Andy (GBR)".toUpperCase());
    ...
                
    return atp_ranking;
  }
...
}

Since the EL resolver returns an instance of the ATPSinglesRankings class in the getValue method, you can easily call the getSinglesRankings, getSinglesRankingsReversed, and getSinglesRankingsUpperCase methods directly from your EL expressions, as shown in the following code:

<b>Ordered:</b><br/>
<h:dataTable id="atpTableId1" value="#{atp.singlesRankings}"var="t">
  <h:column>#{t}</h:column>
</h:dataTable>
<br/><br/><b>Reversed:</b><br/>
<h:dataTable id="atpTableId2" value="#{atp.singlesRankingsReversed}" var="t">
  <h:column>#{t}</h:column>
</h:dataTable>
<br/><br/><b>UpperCase:</b><br/>
<h:dataTable id="atpTableId3" value="#{atp.singlesRankingsUpperCase}" var="t">
  <h:column>#{t}</h:column>
</h:dataTable>

The complete applications to demonstrate custom ELResolvers are available in the code bundle of this chapter and are named ch1_2 and ch1_3.

In order to develop the last example of writing a custom resolver, let's imagine the following scenario: we want to access the ELContext object as an implicit object, by writing #{elContext} instead of #{facesContext.ELContext}. For this, we can use the knowledge accumulated from the previous two examples to write the following custom resolver:

public class ELContextResolver extends ELResolver {

  private static final String EL_CONTEXT_NAME = "elContext";

  @Override
  public Class<?> getCommonPropertyType(ELContext ctx,Object base){
    if (base != null) {
      return null;
    }
    return String.class;
  }

  @Override
  public Iterator<FeatureDescriptor> getFeatureDescriptors(ELContext ctx, Object base) {
    if (base != null) {
      return null;
  }
    ArrayList<FeatureDescriptor> list = new ArrayList<>(1);
    list.add(Util.getFeatureDescriptor("elContext", "elContext","elContext", false, false, true, 
    ELContext.class, Boolean.TRUE));
    return list.iterator();
  }

  @Override
  public Class<?> getType(ELContext ctx, Object base, Object property) {
    if (base != null) {
      return null;
    }
    if (property == null) {
      String message = MessageUtils.getExceptionMessageString(MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "property");
      throw new PropertyNotFoundException(message);
    }
    if ((base == null) && property.equals(EL_CONTEXT_NAME)) {
      ctx.setPropertyResolved(true);
    }
    return null;
  }

  @Override
  public Object getValue(ELContext ctx, Object base, Object property) {

    if ((base == null) && property.equals(EL_CONTEXT_NAME)) {
      ctx.setPropertyResolved(true);
      FacesContext facesContext = FacesContext.getCurrentInstance();
        return facesContext.getELContext();
    }
    return null;
  }

  @Override
  public boolean isReadOnly(ELContext ctx, Object base, Object property) {
    if (base != null) {
      return false;
    }
    if (property == null) {
      String message = MessageUtils.getExceptionMessageString(MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "property");
      throw new PropertyNotFoundException(message);
    }
    if (EL_CONTEXT_NAME.equals(property)) {
      ctx.setPropertyResolved(true);
      return true;
    }
    return false;
  }

  @Override
  public void setValue(ELContext ctx, Object base, Object property, Object value) {
    if (base != null) {
      return;
    }
    ctx.setPropertyResolved(false);
    if (property == null) {
      String message = MessageUtils.getExceptionMessageString(MessageUtils.NULL_PARAMETERS_ERROR_MESSAGE_ID, "property");
      throw new PropertyNotFoundException(message);
    }
    if (EL_CONTEXT_NAME.equals(property)) {
      throw new PropertyNotWritableException((String) property);
    }
  }
}

The complete application is named, ch1_6. The goal of these three examples was to get you familiar with the main steps of writing a custom resolver. In Chapter 3, JSF Scopes – Lifespan and Use in Managed Beans Communication, you will see how to write a custom resolver for a custom scope.

EL 3.0 overview

EL 3.0 (JSR 341, part of Java EE 7) represents a major boost of EL 2.2. The main features of EL 3.0 are as follows:

  • New operators +, =, and ;
  • Lambda expressions
  • Collection objects support
  • An API for standalone environments

In the upcoming sections, you will see how to use EL 3.0 features in JSF pages.

Working with the assignment operator

In an expression of type, x = y, the assignment operator (=), assign the value of y to x. In order to avoid an error of the kind PropertyNotWritableException, the x value must be an lvalue. The following examples show you how to use this operator in two simple expressions:

  • #{x = 3} evaluates to 3
  • #{y = x + 5} evaluates to 8

The assignment operator is right-associative (z = y = x is equivalent with z = (y = x)). For example, #{z = y = x + 4} evaluates to 7.

Working with the string concatenation operator

In an expression of type, x += y, the string concatenation operator (+=) returns the concatenated string of x and y. For example:

  • #{x += y} evaluates to 37
  • #{0 += 0 +=0 += 1 += 1 += 0 += 0 += 0} evaluates to 00011000

In EL 2.2, you can do this using the following code:

#{'0'.concat(0).concat(0).concat(1).concat(1).concat(0).concat(0).concat(0)}

Working with the semicolon operator

In an expression of type, x; y, x is first evaluated, and its value is discarded. Next, y is evaluated and its value is returned. For example, #‌{x = 5; y = 3; z = x + y} evaluates to 8.

Exploring lambda expressions

A lambda expression can be disassembled in three main parts: parameters, the lambda operator (->), and the function body.

Basically, in Java language, a lambda expression represents a method in an anonymous implementation of a functional interface. In EL, a lambda expression is reduced to an anonymous function that can be passed as an argument to a method.

It is important to not confuse Java 8 lambda expressions with EL lambda expressions, but in order to understand the next examples, it is important to know the fundamentals of Java 8 lambda expressions (http://docs.oracle.com/javase/tutorial/java/javaOO/lambdaexpressions.html). They don't have the same syntax, but they are similar enough to not cause notable discomfort when we need to switch between them.

An EL lambda expression is a parameterized ValueExpression object. The body of an EL lambda expression is an EL expression. EL supports several kinds of lambda expressions. The simplest type of EL lambda expressions are immediately invoked, for example:

  • #{(x->x+1)(3)} evaluates to 4
  • #{((x,y,z)->x-y*z)(1,7,3)} evaluates to -20

Further, we have assigned lambda expressions. These are invoked indirectly. For example, #‌{q = x->x+1; q(3)} evaluates to 4.

Indirectly, invocation can be used to write functions. For example, we can write a function to calculate n mod m (without using the % operator). The following example is evaluated to 3:

#‌{modulus = (n,m) -> m eq 0 ? 0 : (n lt m ? n: (modulus(n-m, m))); modulus(13,5)}

We can call this function from other expressions. For example, if we want to calculate the greatest common divisor of two numbers, we can exploit the preceding function; the following example is evaluated to 5:

#‌{gcd = (n,m) -> modulus(n,m) == 0 ? m: (gcd(m, modulus(n,m))); gcd(10, 15)}

Lambda expressions can be passed as arguments to methods. For example, in the following example, you call a method named firstLambdaAction—the lambda expression is invoked from this method:

#‌{lambdaBean.firstLambdaAction(modulus = (n,m) -> m eq 0 ? 0 : (n lt m ? n: (modulus(n-m, m))))}

Now, the firstLambdaAction method is as follows:

public Object firstLambdaAction(LambdaExpression lambdaExpression) {

  //useful in case of a custom ELContext
  FacesContext facesContext = FacesContext.getCurrentInstance();
  ELContext elContext = facesContext.getELContext();
  return lambdaExpression.invoke(elContext, 8, 3);

  //or simply, default ELContext:
  //return lambdaExpression.invoke(8, 3);
}

Another powerful feature of lambda expressions consists of nested lambda expressions. For example (first, is evaluated the inner expression to 7, afterwards the outer expression to as, 10 - 7): #‌{(x->x-((x,y)->(x+y))(4,3))(10)} evaluates to 3.

Do you think EL lambda expressions rocks? Well, get ready for more. The real power is unleashed only when we bring collection objects into equations.

Working with collection objects

EL 3.0 provides powerful support to manipulate collection objects by applying operations in a pipeline. The methods supporting the collection operations are implemented as ELResolvers, and lambda expressions are indicated as arguments for these methods.

The main idea behind manipulating collection objects is based on streams. More precisely, the specific operations are accomplished as method calls to the stream of elements obtained from the collection. Many operations return streams, which can be used in other operations that return streams, and so on. In such a case, we can say that we have a chain of streams or a pipeline. The entry in the pipeline is known as the source, and the exit from the pipeline is known as the terminal operation (this operation doesn't return a stream). Between the source and terminal operation, we may have zero or more intermediate operations (all of them return streams).

The pipeline execution begins when the terminal operation starts. Because intermediate operations are lazy evaluated, they don't preserve intermediate results of the operations (an exception is the sorted operation, which needs all the elements to sort tasks).

Now, let's see some examples. We begin by declaring a set, a list, and a map—EL contains syntaxes to construct sets, lists, and maps dynamically as follows:

#‌{nr_set = {1,2,3,4,5,6,7,8,9,10}}
#‌{nr_list = [1,2,3,4,5,6,7,8,9,10]}
#‌{nr_map = {"one":1,"two":2,"three":3,"four":4,"five":5,"six":6,"seven":7,"eight":8,"nine":9,"ten":10}}

Now, let's go a step further and sort the list in ascending/descending order. For this, we use the stream, sorted (this is like the ORDER BY statement of SQL), and toList methods (the latter returns a List that contains the elements of the source stream), as shown in the following code:

#‌{nr_list.stream().sorted((i,j)->i-j).toList()}
#‌{ nr_list.stream().sorted((i,j)->j-i).toList()}

Further, let's say that we have the following list in a managed bean named LambdaBean:

List<Integer> costBeforeVAT = Arrays.asList(34, 2200, 1350, 430, 57, 10000, 23, 15222, 1);

Next, we can apply 24 percent of VAT and compute the total for costs higher than 1,000 using the filter (this is like SQL's WHERE and GROUP BY statements), map (this is like SQL's SELECT statement), and reduce (this is like the aggregate functions) methods. These methods are used as follows:

#‌{(lambdaBean.costBeforeVAT.stream().filter((cost)-> cost gt 1000).map((cost) -> cost + .24*cost)).reduce((sum, cost) -> sum + cost).get()}

These were just a few examples of using collection objects in EL 3.0. A complete application named ch1_4 is available for download in the code bundle of this chapter. Since, in this application you can see more than 70 examples, I recommend you to take a look at it. Moreover, a nice example can be found on Michael Müller's blog at http://blog.mueller-bruehl.de/web-development/using-lambda-expressions-with-jsf-2-2/.

But, what if we want to take advantage of lambda expressions, but we don't like to write such expressions? Well, a solution can be to write parameterized functions based on lambda expressions, and call them in the JSTL style. For example, the following function is capable of extracting a sublist of a List:

#{get_sublist = (list, left, right)->list.stream().substream(left, right).toList()}

Now, we can call it as shown in the following code:

<ui:repeat value="#{get_sublist(myList, from, to)}" var="t">
  #{t}
</ui:repeat>

In the complete application, named ch1_5, you can see a bunch of 21 parameterized functions that can be used with Lists.

Summary

In this chapter, we saw that EL 2.2 expressions can be used to dynamically access data (read and write) stored in JavaBeans components, to call arbitrary static and public methods, and to perform arithmetic and logic operations. Finally, we saw that EL allows us to extend its capabilities with custom resolvers. Starting with EL 3.0, we can take advantage of new operators, lambda expressions, and support when working with collection objects.

While reading this book, you will see many examples of EL expressions in real cases. For example, in the next chapter, you will use EL expressions to explore JSF communication capabilities.

See you in the next chapter, where we will discuss JSF communications.

Left arrow icon Right arrow icon

Description

A homogenous guide integrating the features of JSF 2.x (2.0, 2.1 and 2.2), following a “learning through examples” paradigm with its main focus on the advanced concepts of JSF. If you are a web developer who uses JSF, this is the book for you. Catering to an intermediate-advanced audience, the book assumes you have fundamental knowledge of JSF. It is intended for the developer who wants to improve their skills with the combined power of JSF 2.0, 2.1, and 2.2.

What you will learn

  • Discover how to write custom JSF 2.2 themes, custom factories, handlers, renderers, and components
  • Access unlimited developing scenarios with the concept of dependency injection
  • Enhance your applications with JSF 2.2 upload component and HTML5 friendly markup
  • Master the new JSF 2.2 Window ID technique
  • Gain insights into managing the application state with stateless viewsExplore the new CDI @ViewScoped and @FlowScoped (detailed presentation)
Estimated delivery fee Deliver to Malta

Premium delivery 7 - 10 business days

€32.95
(Includes tracking information)

Product Details

Country selected
Publication date, Length, Edition, Language, ISBN-13
Publication date : Jun 25, 2014
Length: 578 pages
Edition : 1st
Language : English
ISBN-13 : 9781782176466
Vendor :
Apache
Languages :
Concepts :
Tools :

What do you get with Print?

Product feature icon Instant access to your digital eBook copy whilst your Print order is Shipped
Product feature icon Paperback book shipped to your preferred address
Product feature icon Download this book in EPUB and PDF formats
Product feature icon Access this title in our online reader with advanced features
Product feature icon DRM FREE - Read whenever, wherever and however you want
Estimated delivery fee Deliver to Malta

Premium delivery 7 - 10 business days

€32.95
(Includes tracking information)

Product Details

Publication date : Jun 25, 2014
Length: 578 pages
Edition : 1st
Language : English
ISBN-13 : 9781782176466
Vendor :
Apache
Languages :
Concepts :
Tools :

Packt Subscriptions

See our plans and pricing
Modal Close icon
€18.99 billed monthly
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Simple pricing, no contract
€189.99 billed annually
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts
€264.99 billed in 18 months
Feature tick icon Unlimited access to Packt's library of 7,000+ practical books and videos
Feature tick icon Constantly refreshed with 50+ new titles a month
Feature tick icon Exclusive Early access to books as they're written
Feature tick icon Solve problems while you work with advanced search and reference features
Feature tick icon Offline reading on the mobile app
Feature tick icon Choose a DRM-free eBook or Video every month to keep
Feature tick icon PLUS own as many other DRM-free eBooks or Videos as you like for just €5 each
Feature tick icon Exclusive print discounts

Frequently bought together


Stars icon
Total 86.98
Primefaces Cookbook Second Edition
€36.99
Mastering JavaServer Faces 2.2
€49.99
Total 86.98 Stars icon

Table of Contents

14 Chapters
1. Dynamic Access to JSF Application Data through Expression Language (EL 3.0) Chevron down icon Chevron up icon
2. Communication in JSF Chevron down icon Chevron up icon
3. JSF Scopes – Lifespan and Use in Managed Beans Communication Chevron down icon Chevron up icon
4. JSF Configurations Using XML Files and Annotations – Part 1 Chevron down icon Chevron up icon
5. JSF Configurations Using XML Files and Annotations – Part 2 Chevron down icon Chevron up icon
6. Working with Tabular Data Chevron down icon Chevron up icon
7. JSF and AJAX Chevron down icon Chevron up icon
8. JSF 2.2 – HTML5 and Upload Chevron down icon Chevron up icon
9. JSF State Management Chevron down icon Chevron up icon
10. JSF Custom Components Chevron down icon Chevron up icon
11. JSF 2.2 Resource Library Contracts – Themes Chevron down icon Chevron up icon
12. Facelets Templating Chevron down icon Chevron up icon
A. The JSF Life Cycle Chevron down icon Chevron up icon
Index Chevron down icon Chevron up icon

Customer reviews

Most Recent
Rating distribution
Full star icon Full star icon Full star icon Full star icon Half star icon 4.3
(15 Ratings)
5 star 60%
4 star 26.7%
3 star 6.7%
2 star 0%
1 star 6.7%
Filter icon Filter
Most Recent

Filter reviews by




Ahmed Mansour Aug 09, 2023
Full star icon Full star icon Full star icon Full star icon Full star icon 5
to master jsf that's all you need
Amazon Verified review Amazon
donald c conway Oct 31, 2017
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Excellent book on using JSF
Amazon Verified review Amazon
MMT Mar 12, 2017
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
Good book as a starter...
Amazon Verified review Amazon
Jesper De Jong Nov 03, 2016
Full star icon Full star icon Full star icon Full star icon Empty star icon 4
This book contains a wealth of information about JavaServer Faces, which is very valuable for you if you are working on web applications implemented with JSF. But the format of the book is strange. The book does not have a very clear structure, it looks like a collection of notes on various aspects of JSF. There is no clear story or progression going through the book from beginning to end.If you are completely new to JSF and you expect a tutorial learning you how to use JSF step by step, then this book is definitely not for you.If you already understand the basics and you want to have a reference manual with lots of useful bits of information on using JSF, then this book is very useful.
Amazon Verified review Amazon
Nubye Oct 25, 2016
Full star icon Full star icon Full star icon Full star icon Full star icon 5
Very practical. I recommend first read JavaServer Faces: Introduction by ExampleJuneau, Josh.
Amazon Verified review Amazon
Get free access to Packt library with over 7500+ books and video courses for 7 days!
Start Free Trial

FAQs

What is the delivery time and cost of print book? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela
What is custom duty/charge? Chevron down icon Chevron up icon

Customs duty are charges levied on goods when they cross international borders. It is a tax that is imposed on imported goods. These duties are charged by special authorities and bodies created by local governments and are meant to protect local industries, economies, and businesses.

Do I have to pay customs charges for the print book order? Chevron down icon Chevron up icon

The orders shipped to the countries that are listed under EU27 will not bear custom charges. They are paid by Packt as part of the order.

List of EU27 countries: www.gov.uk/eu-eea:

A custom duty or localized taxes may be applicable on the shipment and would be charged by the recipient country outside of the EU27 which should be paid by the customer and these duties are not included in the shipping charges been charged on the order.

How do I know my custom duty charges? Chevron down icon Chevron up icon

The amount of duty payable varies greatly depending on the imported goods, the country of origin and several other factors like the total invoice amount or dimensions like weight, and other such criteria applicable in your country.

For example:

  • If you live in Mexico, and the declared value of your ordered items is over $ 50, for you to receive a package, you will have to pay additional import tax of 19% which will be $ 9.50 to the courier service.
  • Whereas if you live in Turkey, and the declared value of your ordered items is over € 22, for you to receive a package, you will have to pay additional import tax of 18% which will be € 3.96 to the courier service.
How can I cancel my order? Chevron down icon Chevron up icon

Cancellation Policy for Published Printed Books:

You can cancel any order within 1 hour of placing the order. Simply contact customercare@packt.com with your order details or payment transaction id. If your order has already started the shipment process, we will do our best to stop it. However, if it is already on the way to you then when you receive it, you can contact us at customercare@packt.com using the returns and refund process.

Please understand that Packt Publishing cannot provide refunds or cancel any order except for the cases described in our Return Policy (i.e. Packt Publishing agrees to replace your printed book because it arrives damaged or material defect in book), Packt Publishing will not accept returns.

What is your returns and refunds policy? Chevron down icon Chevron up icon

Return Policy:

We want you to be happy with your purchase from Packtpub.com. We will not hassle you with returning print books to us. If the print book you receive from us is incorrect, damaged, doesn't work or is unacceptably late, please contact Customer Relations Team on customercare@packt.com with the order number and issue details as explained below:

  1. If you ordered (eBook, Video or Print Book) incorrectly or accidentally, please contact Customer Relations Team on customercare@packt.com within one hour of placing the order and we will replace/refund you the item cost.
  2. Sadly, if your eBook or Video file is faulty or a fault occurs during the eBook or Video being made available to you, i.e. during download then you should contact Customer Relations Team within 14 days of purchase on customercare@packt.com who will be able to resolve this issue for you.
  3. You will have a choice of replacement or refund of the problem items.(damaged, defective or incorrect)
  4. Once Customer Care Team confirms that you will be refunded, you should receive the refund within 10 to 12 working days.
  5. If you are only requesting a refund of one book from a multiple order, then we will refund you the appropriate single item.
  6. Where the items were shipped under a free shipping offer, there will be no shipping costs to refund.

On the off chance your printed book arrives damaged, with book material defect, contact our Customer Relation Team on customercare@packt.com within 14 days of receipt of the book with appropriate evidence of damage and we will work with you to secure a replacement copy, if necessary. Please note that each printed book you order from us is individually made by Packt's professional book-printing partner which is on a print-on-demand basis.

What tax is charged? Chevron down icon Chevron up icon

Currently, no tax is charged on the purchase of any print book (subject to change based on the laws and regulations). A localized VAT fee is charged only to our European and UK customers on eBooks, Video and subscriptions that they buy. GST is charged to Indian customers for eBooks and video purchases.

What payment methods can I use? Chevron down icon Chevron up icon

You can pay with the following card types:

  1. Visa Debit
  2. Visa Credit
  3. MasterCard
  4. PayPal
What is the delivery time and cost of print books? Chevron down icon Chevron up icon

Shipping Details

USA:

'

Economy: Delivery to most addresses in the US within 10-15 business days

Premium: Trackable Delivery to most addresses in the US within 3-8 business days

UK:

Economy: Delivery to most addresses in the U.K. within 7-9 business days.
Shipments are not trackable

Premium: Trackable delivery to most addresses in the U.K. within 3-4 business days!
Add one extra business day for deliveries to Northern Ireland and Scottish Highlands and islands

EU:

Premium: Trackable delivery to most EU destinations within 4-9 business days.

Australia:

Economy: Can deliver to P. O. Boxes and private residences.
Trackable service with delivery to addresses in Australia only.
Delivery time ranges from 7-9 business days for VIC and 8-10 business days for Interstate metro
Delivery time is up to 15 business days for remote areas of WA, NT & QLD.

Premium: Delivery to addresses in Australia only
Trackable delivery to most P. O. Boxes and private residences in Australia within 4-5 days based on the distance to a destination following dispatch.

India:

Premium: Delivery to most Indian addresses within 5-6 business days

Rest of the World:

Premium: Countries in the American continent: Trackable delivery to most countries within 4-7 business days

Asia:

Premium: Delivery to most Asian addresses within 5-9 business days

Disclaimer:
All orders received before 5 PM U.K time would start printing from the next business day. So the estimated delivery times start from the next day as well. Orders received after 5 PM U.K time (in our internal systems) on a business day or anytime on the weekend will begin printing the second to next business day. For example, an order placed at 11 AM today will begin printing tomorrow, whereas an order placed at 9 PM tonight will begin printing the day after tomorrow.


Unfortunately, due to several restrictions, we are unable to ship to the following countries:

  1. Afghanistan
  2. American Samoa
  3. Belarus
  4. Brunei Darussalam
  5. Central African Republic
  6. The Democratic Republic of Congo
  7. Eritrea
  8. Guinea-bissau
  9. Iran
  10. Lebanon
  11. Libiya Arab Jamahriya
  12. Somalia
  13. Sudan
  14. Russian Federation
  15. Syrian Arab Republic
  16. Ukraine
  17. Venezuela