Recipe12.6.Displaying Locale-Specific Text


Recipe 12.6. Displaying Locale-Specific Text

Problem

Your Struts application needs to display correctly formatted textparticularly numbers, dates, and messagesbased on a user's locale.

Solution

From the Struts bean tag library, use the following:

<%-- Format a number --%> <bean:write name="beanName"         property="numericProperty"           format="number pattern"/> <%-- Format a date --%> <bean:write name="beanName"         property="dateProperty"           format="date pattern"/> <%-- Format a message with parameters --%> <bean:message key="message.key"              argn="replacement value"/>

From the JSTL fmt tag library, use the following:

<%-- Format a number --%> <fmt:formatNumber value="${beanName.numericProperty}"                 pattern="number pattern"/>      <%-- Format a date --%> <fmt:formatDate value="${beanName.dateProperty}"               pattern="date pattern"/> <%-- Format a message with parameters --%> <fmt:message key="message.key">     <fmt:param value="replacement value"/> </fmt:message>

Discussion

Struts provides the generic bean:write tag to output text formatted for a specific locale and bean:message to render localized messages. If you're using JSTL, you can use the tags of the fmt tag library.

Recipe 12.6.3.1 Using the Struts bean tags

This bean:write tag renders a value specified by the standard Struts name and property attributes. This tag can format dates and numbers before outputting the value using the pattern specified by the format attribute. The format pattern will be applied if the value is a java.lang.Number or java.util.Date object. Numbers are formatted using the java.text.DecimalFormat class and dates with the java.text.SimpleDateFormat class.

The bean:write tag accounts for the current locale when formatting by using a locale-specific instance of the formatter class. For example, suppose you are outputting a numeric value:

<bean:write name="order" property="amount" format="#,##0.00"/>

With the locale set to English ("en") and the amount to 13995.78, the following text is rendered:

13,995.78

With the locale set to Russian ("ru"), the number is formatted for that locale. Like other European languages, Russian uses a space for the grouping separator and a comma (,) for the decimal separator.

13 995,78

You can use the formatKey attribute of the bean:write tag to refer to a pattern stored in your message resources bundle. For numbers, the pattern retrieved from the bundle will be applied as a localized pattern; in other words, the pattern is expected to be written for that specific locale.

If you use the formatKey attribute of the bean:write tag, be aware of a known issue (Apache Bugzilla ticket #27636): you must specify a value for the key in all of your resource bundles that may use it. Because the pattern is applied as a localized pattern, a nonlocalized pattern retrieved from a fallback resource bundle can result in meaningless output. Date patterns are not applied as localized patterns and are not affected by this issue.


For the pattern used in the previous example, you would store a name/value pair in ApplicationResources_en.properties like the following:

format.amount = #,##0.00

In the properties file localized for Russian (ApplicationResources_ru.properties), you would have:

format.amount = # ##0,00

This formatKey attribute proves more useful when working with dates. Say you wanted to generate dates such as Sep 14, 2004 for English and 14 __ _ 2004 for Russian. In your English properties file, you would have the following:

format.date=MMM dd, yyyy

In the Russian properties file, you would use the following:

format.date=dd MMM yyyy

You could use one bean:write tag to render the date in the appropriate format using the following:

<bean:write name="order" property="datePlaced" formatKey="format.date"/>

For messages, use the bean:message tag. Suppose you want to render an order confirmation message on a "success" page. The message should display the quantity of items ordered, the part number, and the total cost. Here's one way you could specify the message in your base resource bundle (ApplicationResources.properties):

msg.confirm.order=You ordered {0} of part {1} at a total cost of ${2}.

On a JSP page, the bean:message tag retrieves the message by key. The argn attributes contain the substitution values. Unless you are using the Struts-EL version of the bean tags or a JSP 2.0 container, you must resort to scriptlet for the substitution arguments:

<!-- Create a scripting variable --> <bean:define  name="order"  type="com.oreilly.strutsckbk.ch12. Order"/> <!-- Render the message --> <bean:message key="msg.confirm.order"              arg0="<%=theOrder.getQuantity( ).toString( )%>"              arg1="<%=theOrder.getPartNumber( ).toString( )%>"              arg2="<%=theOrder.getAmount( ).toString( )%>" />

To display the message for a different locale, like Spanish, you only need to place the translated message into that locale's resource bundle (ApplicationResources_es.properties):

 msg.confirm.order = Usted ordeno {0} unidades de parte {1}  resultando en un costo total de ${2}.

The bean:message tag formats the message using the java.text.MessageFormat class. This class even allows you to format the replacement values themselves using a special notation. Check the JavaDocs for this class (online at http://java.sun.com/j2se/1.4.2/docs/api/java/text/MessageFormat.html) if you are using this mechanism.

Recipe 12.6.3.2 Using the JSTL format tags

The JSTL formatting tags provide similar capabilities as the Struts tags. The JSTL fmt tag library provides two primary tags for localizing data. The fmt:formatNumber tag formats numeric values. You can specify a specific pattern, or you can specify characteristics such as the minimum and maximum digits. If you are migrating from using bean:write and were using the format attribute to specify a pattern, you can use that same pattern with JSTL:

<fmt:formatNumber value="${order.amount}" pattern="#,##0.00"/>

If you were using the bean:write's formatKey attribute, the corresponding pattern can only be used if it localized the server's default locale. Unlike the bean:write tag, JSTL number formatting tags don't expect the pattern to be localized.


For formatting dates and times, use the fmt:formatDate tag. Like the fmt:formatNumber tag, you can specify a pattern or formatting characteristics, such as a date style. If you were using bean:write's formatKey attribute to use a pattern from a resource bundle, you can achieve the same affect with JSTL.

<fmt:message key="format.date" var="dateFmt"/> <fmt:formatDate value="${order.datePlaced}" pattern="${dateFmt}"/>

Like the bean:message tag, JSTL's fmt:message tag builds and localizes messages from a resource bundle. The fmt:param tag substitutes a value for a message parameter placeholder.

<fmt:message key="msg.confirm.order">     <fmt:param value="${order.quantity}"/>     <fmt:param value="${order.partNumber}"/>     <fmt:param value="${order.amount}"/> <fmt:message key="msg.confirm.order">

All in all, JSTL tags tend to be less verbose and cleaner than the corresponding Struts tags. More importantly, the power of the JSTL expression language (EL) alleviates the need for request-time expressions and scriptlet.

See Also

Check out the Struts User's Guide for more details. The documentation for the bean tag library can be found at http://struts.apache.org/userGuide/struts-bean.html.

For a good source on the JSTL tags, check out Java Server Pages by Hans Bergsten (O'Reilly).

Struts issues are tracked using Bugzilla. You can browse the issues at http://issues.apache.org/bugzilla.



    Jakarta Struts Cookbook
    Jakarta Struts Cookbook
    ISBN: 059600771X
    EAN: 2147483647
    Year: 2005
    Pages: 200

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