Using Standard Converters

   

In the following sections, we cover the converters and validators that are a part of the JSF library. Later in this chapter, you learn how to supply your own validation code if your needs go beyond the basics.

Conversion of Numbers and Dates

A web application stores data of many types, but the web user interface deals exclusively with strings. For example, suppose the user needs to edit a Date object that is stored in the business logic. First, the Date object is converted to a string that is sent to the client browser to be displayed inside a textfield. The user then edits the textfield. The resulting string is returned to the server and must be converted back to a Date object.

The same situation holds, of course, for primitive types such as int, double, or boolean. The user of the web application edits strings, and the JSF container needs to convert the string to the type required by the application.

To see a typical use of a built-in converter, imagine a web application that is used to process payments (see Figure 6-2). The payment data includes

  • the amount to be charged

  • the credit card number

  • the credit card expiration date

Figure 6-2. Processing payments

graphics/06fig02.jpg


We attach a converter to the textfield and tell it to format the current value with at least two digits after the decimal point:

 

 <h:inputText value="#{payment.amount}">    <f:convertNumber minFractionDigits="2"/> </h:inputText> 

The f:convertNumber converter is one of the standard converters supplied by the JSF implementation.

The second field in this screen does not use a converter. (Later in this chapter, we attach a custom converter.) The third field uses an f:datetime converter whose pattern attribute is set to the string MM/yyyy. (The pattern string format is documented in the API documentation for the java.text.SimpleDateFormat class.)

 

 <h:inputText value="#{payment.date}">    <f:convertDateTime pattern="MM/yyyy"/> </h:inputText> 

In the result.jsp page, we show the inputs that the user provided, using a different converter for the payment amount:

 

 <h:outputText value="#{payment.amount}">    <f:convertNumber type="currency"/> </h:outputText> 

This converter automatically supplies a currency symbol and decimal separators (see Figure 6-3).

Figure 6-3. Displaying the Payment Information

graphics/06fig03.jpg


Converters and Attributes

Tables 6-1 and 6-2 show the standard converters and their attributes.

Table 6-1. Attributes of the f:convertNumber tag

Attribute

Type

Value

type

String

number (default), currency, or percent

pattern

String

Formatting pattern, as defined in java.text.DecimalFormat

xaxFractionDigits

int

Maximum number of digits in the fractional part

minFractionDigits

int

Minimum number of digits in the fractional part

maxIntegerDigits

int

Maximum number of digits in the integer part

minIntegerDigits

int

Minimum number of digits in the integer part

integerOnly

boolean

True if only the integer part is parsed (default: false)

groupingUsed

boolean

True if grouping separators are used (default: true)

locale

java.util.Locale

Locale whose preferences are to be used for parsing and formatting

currencyCode

String

ISO 4217 currency code to use when converting currency values

currencySymbol

String

Currency symbol to use when converting currency values


Table 6-2. Attributes of the f:convertDateTime tag

Attribute

Type

Value

type

String

Date (default), time, or both

dateStyle

String

default, short, medium, long, or full

timeStyle

String

default, short, medium, long, or full

pattern

String

Formatting pattern, as defined in java.text.SimpleDateFormat

locale

java.util.Locale

Locale whose preferences are to be used for parsing and formatting

timeZone

java.util.TimeZone

Time zone to use for parsing and formatting


NOTE

graphics/note_icon.gif

If you use a value binding whose type is either a primitive type or BigInteger/BigDecimal, then you don't need to specify any converter. The JSF implementation automatically picks a standard converter. However, you need to specify an explicit converter for Date values.


The converter Attribute

An alternate syntax for attaching a converter to a component is to add the converter attribute to the component tag. You specify the ID of the converter like this:

 

 <h:outputText value="#{payment.date}" converter="javax.faces.DateTime"/> 

This is equivalent to using f:convertDateTime with no attributes:

 

 <h:outputText value="#{payment.date}">    <f:convertDateTime/> </h:outputText> 

All JSF implementations must define a set of converters with predefined IDs:

  • javax.faces.DateTime (used by f:convertDateTime)

  • javax.faces.Number (used by f:convertNumber)

  • javax.faces.Boolean, javax.faces.Byte, javax.faces.Character, javax.faces.Double, javax.faces.Float, javax.faces.Integer, javax.faces.Long, javax.faces.Short (automatically used for primitive types and their wrapper classes)

  • javax.faces.BigDecimal, javax.faces.BigInteger (automatically used for BigDecimal/BigInteger)

Additional converter IDs can be configured in an application configuration file see page 226 for details.

CAUTION

graphics/caution_icon.gif

When the value of the converter attribute is a string, then the value indicates the ID of a converter. However, if it is a value binding expression, then its value must be a converter object an object of a class that implements the Converter interface. That interface is introduced on page 223.


Conversion Errors

When a conversion error occurs, the following actions are the result:

  • The component whose conversion failed posts a message and declares itself invalid. (You see in the next section how to display the message.)

  • The JSF implementation redisplays the current page immediately after the "Process Validations" phase has completed.

This behavior is generally desirable. If a user provides an illegal input for, say, a field that requires an integer, then the web application should not try to use that illegal input. The JSF implementation automatically redisplays the current page, giving the user another chance to enter the value correctly.

However, you should avoid overly restrictive conversion options for input fields. For example, consider the "amount" field in our example. Had we used a currency format, then the current value would have been nicely formatted. But suppose a user enters 100 (without a leading $ sign). The currency formatter will complain that the input is not a legal currency value. That's too strict for human use.

To overcome this problem, you can program a custom converter. A custom converter can format a value prettily, yet be lenient when interpreting human input. Custom converters are described later in this chapter.

TIP

graphics/exclamatory_icon.gif

When gathering input from the user, you should either use a lenient converter or simply redesign your form to be more user friendly. For example, rather than forcing users to format the expiration date as MM/dddd, you can supply two input fields, one for the month and another for the year.


Displaying Error Messages

Of course, it is important that the user be able to see the messages that are caused by conversion and validation errors. You should add h:message tags whenever you use converters and validators.

Normally, you want to show the error messages next to the components that reported them (see Figure 6-4). Give an ID to the component, and reference that ID in the h:message tag.

 

 <h:inputText  value="#{payment.amount}"/> <h:message for="amount"/> 

Figure 6-4. Displaying a Conversion Error Message

graphics/06fig04.jpg


The h:message tag takes a number of attributes to describe the appearance of the message see Chapter 4 for details. Here, we discuss only the attributes that are of particular interest for error reporting.

A message has two parts: summary and detail. By default, the h:message tag shows the detail and hides the summary. If you want to show the summary message instead, use these attributes:

 

 <h:message for="amount" showSummary="true" showDetail="false"/> 

CAUTION

graphics/caution_icon.gif

If you use a standard converter, display either the summary message or the detail message, but not both for some errors, the messages are identical. You don't want your users to ponder an error message that reads "Conversion error occurred. Conversion error occurred."


You use the styleClass or style attribute to change the appearance of the error message:

 

 <h:messages style/> 

or

 

 <h:message for="amount" style="color:red"/> 

We recommend that you use styleClass and a stylesheet instead of a hard-coded style.

Displaying All Error Messages

It is uncommon to have multiple messages for one component, but it can happen. The h:message tag produces only the first message. Unfortunately, you don't know whether the first message is the most useful one for the user. While no tag shows all messages for a particular component, you can show a listing of all messages from all components with the h:messages tag.

By default, the h:messages tag shows the message summary but not the message detail. This behavior is opposite from that of the h:message tag.

For h:messages, you usually want to set the layout attribute to "table" so that the messages are lined up vertically. Otherwise they are simply concatenated.

 

 <h:messages layout="table"/> 

TIP

graphics/exclamatory_icon.gif

Whenever you create a message, make sure it ends with a period and a space, to ensure a neat appearance when messages are concatenated.


However, we find it difficult to believe that anyone would actually use the h:messages tag in a form with multiple input fields. Suppose a user happened to fill in two fields incorrectly. The h:messages tag would display two "Conversion error occurred" messages, with no indication of the offending fields.

TIP

graphics/exclamatory_icon.gif

The h:messages tag is useful for debugging. Whenever your JSF application stalls at a particular page and is unwilling to move on, add a <h:messages/> tag to see if a failed conversion or validation is the culprit.


Changing the Text of Standard Error Messages

As you saw in Figure 6-4, the default error message for a conversion error is "Conversion error occurred." If you think that your audience is unfamiliar with the concept of data conversion, you may want to change this message.

Set up a message bundle, as explained in Chapter 2. Add the replacement message, using the key javax.faces.component.UIInput.CONVERSION. For example,

 

 javax.faces.component.UIInput.CONVERSION=Please correct your input. 

Then set the base name of the bundle in a configuration file (such as faces-config.xml):

 

 <faces-config>    <application>       <message-bundle>com.corejsf.messages</message-bundle>    </application>    ... </faces-config> 

A Complete Converter Example

We are now ready for our first complete example. Figure 6-5 shows the directory structure of the application. This web application simply asks the user to supply payment information (Listing 6-1), and then displays the formatted information on a confirmation screen (Listing 6-2). The messages are in Listing 6-3 and the bean class is in Listing 6-4.

Listing 6-1. converter/index.jsp
  1. <html>  2.    <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>  3.    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>  4.    <f:view>  5.       <head>  6.          <link href="styles.css" rel="stylesheet" type="text/css"/>  7.          <f:loadBundle basename="com.corejsf.messages" var="msgs"/>  8.          <title><h:outputText value="#{msgs.title}"/></title>  9.       </head> 10.       <body> 11.          <h:form> 12.             <h1><h:outputText value="#{msgs.enterPayment}"/></h1> 13.             <h:panelGrid columns="3"> 14.                <h:outputText value="#{msgs.amount}"/> 15.                <h:inputText  value="#{payment.amount}"> 16.                   <f:convertNumber minFractionDigits="2"/> 17.                </h:inputText> 18.                <h:message for="amount" style/> 19. 20.                <h:outputText value="#{msgs.creditCard}"/> 21.                <h:inputText  value="#{payment.card}"/> 22.                <h:panelGroup/> 23. 24.                <h:outputText value="#{msgs.expirationDate}"/> 25.                <h:inputText  value="#{payment.date}"> 26.                   <f:convertDateTime pattern="MM/yyyy"/> 27.                </h:inputText> 28.                <h:message for="date" style/> 29.             </h:panelGrid> 30.             <h:commandButton value="#{msgs.process}" action="process"/> 31.          </h:form> 32.       </body> 33.    </f:view> 34. </html> 

Listing 6-2. converter/result.jsp
  1. <html>  2.    <%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>  3.    <%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>  4.    <f:view>  5.       <head>  6.          <link href="styles.css" rel="stylesheet" type="text/css"/>  7.          <f:loadBundle basename="com.corejsf.messages" var="msgs"/>  8.          <title><h:outputText value="#{msgs.title}"/></title>  9.       </head> 10.       <body> 11.          <h:form> 12.             <h1><h:outputText value="#{msgs.paymentInformation}"/></h1> 13.             <h:panelGrid columns="2"> 14.                <h:outputText value="#{msgs.amount}"/> 15.                <h:outputText value="#{payment.amount}"> 16.                   <f:convertNumber type="currency"/> 17.                </h:outputText> 18. 19.                <h:outputText value="#{msgs.creditCard}"/> 20.                <h:outputText value="#{payment.card}"/> 21. 22.                <h:outputText value="#{msgs.expirationDate}"/> 23.                <h:outputText value="#{payment.date}"> 24.                   <f:convertDateTime pattern="MM/yyyy"/> 25.                </h:outputText> 26.             </h:panelGrid> 27.             <h:commandButton value="Back" action="back"/> 28.          </h:form> 29.       </body> 30.    </f:view> 31. </html> 

Listing 6-3. converter/WEB-INF/classes/com/corejsf/messages.properties
 1. title=An Application to Test Data Conversion 2. enterPayment=Please enter the payment information: 3. amount=Amount: 4. creditCard=Credit Card: 5. expirationDate=Expiration date (Month/Year): 6. process=Process 7. paymentInformation=Payment information 

Listing 6-4. converter/WEB-INF/classes/com/corejsf/PaymentBean.java
  1. package com.corejsf;  2.  3. import java.util.Date;  4.  5. public class PaymentBean {  6.    private double amount;  7.    private String card = "";  8.    private Date date = new Date();  9. 10.    // PROPERTY: amount 11.    public void setAmount(double newValue) { amount = newValue; } 12.    public double getAmount() { return amount; } 13. 14.    // PROPERTY: card 15.    public void setCard(String newValue) { card = newValue; } 16.    public String getCard() { return card; } 17. 18.    // PROPERTY: date 19.    public void setDate(Date newValue) { date = newValue; } 20.    public Date getDate() { return date; } 21. } 

Figure 6-5. Directory Structure of the Converter Sample

graphics/06fig05.jpg




core JavaServer Faces
Core JavaServer Faces
ISBN: 0131463055
EAN: 2147483647
Year: 2003
Pages: 121

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net