8.2 Presentation Layer

I l @ ve RuBoard

JavaServer Pages (JSP) technology is the preferred technology for developing user interfaces in the Java 2 Enterprise Edition (J2EE). The technology was developed to separate the presentation of dynamic content from the components responsible for generating the business logic. It also allows for separation of roles between user interface designers and application designers.

8.2.1 Do Not Rely on Browser Settings for Storing Localization Preferences

In designing your presentation layer, you need to be concerned with where you pull localization information to drive the presentation of the user interface. In other words, how are your JSP pages supposed to know that they should present the information for one user in English and information for another user in Hebrew?

The Internet Explorer Language Preference dialog, as shown in Figure 8-1, allows the user to configure the languages he would like to see in order of preference. A setting such as this will affect certain HTTP headers such as the Accept-Language header. You might think this is great for you as an application developer; you no longer have to be concerned about where to pull a user's preferred localization information. Simply grab that information from the request headers and use it to drive your user interface.

Figure 8-1. Language preference dialog from Internet Explorer
figs/jebp_0801.gif

There are a number of reasons why relying on a browser's settings or, for that matter, the user's ability to configure these settings will get you into trouble:

  • The browser's settings are outside the scope of your application. Although most browsers on the market today do offer the ability to configure language preference settings, it is not a requirement and therefore might not be present in the configuration. If this is the case, you must drive the localization preference from another setting.

  • The fewer configuration settings a user has to manage or remember to use your application, the better. It's not that a user of web-based applications is not savvy enough to adjust the browser's language settings appropriately, but she might not want to use your application if she has to change browser settings each time.

  • The user might configure localization settings that are not supported by your application. That is, she might configure the browser for Russian when in fact your application supports only English, Italian, and Spanish. However, in this case, an application can be proactive in notifying the user that a particular localization is not supported by the application (but now the user has to readjust her browser settings again.)

  • The browser's settings are typically user-dependent or profile-based. So it can be a hassle to reconfigure a colleague's browser settings if, for example, you are not at your local desktop.

The point here is that the localization settings should not be driven by a browser setting, but instead by a configuration option in the application. The supported localizations for an application can be stored in a user's profile when a user registers or signs onto an application.

How should you proceed? First, you should present only the valid localizations for an application. As mentioned earlier, if your application is localized only for English, Italian, and Spanish, do not offer any other choices to the user.

You'll also need to decide where to store the localization preference. This is often a method that is called on the User object defined for your application. For example, you might have a method, getLocalizationPreference( ) , which returns a java.util.Locale object indicating the user's localization preference. This locale object can then be passed to appropriate methods on custom tags in the user interface, to the proper business logic methods in the business object layer, or to the data access layer to retrieve localized data from a back-end datastore.

Another possibility is to store the localization preference as an attribute held in the user's session that would be accessible from JSPs and servlets in your application. For example, the session variable com.oreilly.bestpractices.j2ee.i18n.USER_PREFERRED_LOCALE could be used to store the user's localization preference as a Locale object. Initially, this object would be set by the application to a default localization preference for the application. Once a user logs into the J2EE application, this variable would be updated to reflect the user's preference. It would also be updated once a user changes his localization preference within the application.

8.2.2 Use JSP Custom Tags or the JSTL for Locale-Specific Data Presentation

No doubt, if you've used the JSP technology in the past, or if you've heard or read discussions on the topic, you can run into trouble by embedding too much Java code in your JSP pages. A reusable and component-based approach to removing Java code from your JSP pages is to use custom tags. As you broaden your scope from the user's language preference, an application will need to present data to the user. Certain data elements such as text, numbers , dates, and times will need to be presented in the most locale-specific manner possible.

A number of tag libraries are available for presenting data in a locale-specific way. The JavaServer Pages Standard Tag Library (JSTL) [3] falls under Java Specification Request (JSR) 52 and provides you with a common set of tags that you would expect to see when developing J2EE-based applications that use the JSP technology. A number of tags that handle internationalization formatting fall under the JSTL. Chapters 8 and 9 of the JSTL specification discuss all the relevant details of the tags specific to internationalization and localization.

[3] The specification for the JSTL, or JSR 52, can be found online at http://jcp.org/aboutJava/communityprocess/first/jsr052/.

A more formal discussion of JSP custom tags (and developing these tags) is outside the scope of this chapter. However, we would like to cover an example of using the JSTL. Example 8-1 demonstrates the use of the JSTL using Tomcat 4.0.3 running under Java 2 SDK 1.4.0 under Windows 95. You can download the JSTL Reference Implementation and Tomcat from the Jakarta web site (http://jakarta.apache.org).

Example 8-1 shows part of the FormatNumber.jsp included with the JSTL demonstration web application. It demonstrates how simple the JSP tags are to use in your JSP pages.

Example 8-1. JSTL demonstration application showing use of internationalization-specific JSTL tags
 // Above JSP code removed      <li> Format &quot;12345.67&quot; as German currency (given string is       parsed using &quot;en&quot; locale before it is formatted):<br>   <fmt:setLocale value="de-DE"/>   <fmt:formatNumber value="12345.67" type="currency"/>  </ul>     </body> </html> 

Figure 8-2 is a rendering of a JSP page that demonstrates locale-specific formatting from the examples shipped with the JSTL. Try changing the language settings in your browser to see how certain tags pull information from the HTTP request to determine which locale to use to display data.

Figure 8-2. Formatting using the JSTL tags
figs/jebp_0802.gif

A common feature of web-based applications is the use of forms to collect data from a user. Forms can be relatively straightforward, as shown in Example 8-2.

Example 8-2. Simple HTML form
 <html>     <head> <title>Simple form page</title> </head>     <body>     Hi, we'd like to collect some information about you.      <form action="user-information-collector.jsp" name="user_information" method="post"> First name: <input type="text" name="first_name"> Last name: <input type="text" name="last_name"> Checking account balance: <input type="text" name="checking_account_balance"> </form>     </body>     </html> 

Each form item, when read by a servlet or another JSP page, can contain information that needs to be read in a locale-specific way. Why? The character encoding will differ depending on the user entering the information. For U.S. English, a user entering information into that form will typically have entered the information in the ISO-8859-1 character encoding. However, for Japanese, the character encoding will most likely be Shift-JIS.

What steps can you take to ensure that your forms can be read correctly? The simplest approach is to add a hidden element to the form indicating the character encoding that was used to enter the information in the form. You can get this element from the user's language-preference setting, and it typically looks like this:

 <input type="hidden" name="input_character_set" value="Shift_JIS"> 

On the server side, the code you use to read the form items will need to use this character set value to convert the data appropriately. This value is passed to the setCharacterEncoding(String encoding) method on the ServletRequest object so that the form parameters can be parsed using the character set of the form.

HTML forms can also be quite complex, performing custom formatting and validation of the data. Among other things, this helps to ensure that certain form elements that are required by an application contain data and that the data in all form elements conforms to a specific type that can introduce locale-specific complexities. This would be necessary if, for example, you have to validate a price field on a form for English, French, and German.

A very comprehensive and freely available tag library for performing locale-specific form validation is available from a company called SQL Technology. [4] The custom tag library is called PBP. In addition to JSP tags to do formatting, PBP contains a set of tags for generating locale-specific forms containing localized client-side JavaScript for appropriate form validation. Figures 8-3 and 8-4 demonstrate the PBP Custom Tag Library running in English and Italian, respectively.

[4] Information about the SQLT tag library can be found online at http://www.sqlt.com/taglib.html.

Figure 8-3. The SQLT PBP Custom Tag Library using the American rules for validation
figs/jebp_0803.gif
Figure 8-4. The SQLT PBP Custom Tag Library using the Italian rules for validation
figs/jebp_0804.gif

Notice in Figure 8-4 that the date field is formatted as appropriate for Italian. Attempting to submit the form will also validate the contents of this form item as appropriate for Italian.

8.2.3 Take a Portal-Based Approach to JSP Development

In David's article on Java, "Designing Internationalized User-Interface Components for Web Applications," [5] the use of JSP custom tags for the presentation of localized data in JSP pages was discussed. In that article, the InsertText tag not only pulled a specific item from a resource bundle, but it also handled issues with text direction. In certain locales, text can be written from left to right or right to left, or it can be bidirectional. Arabic and Hebrew are the canonical examples of languages that are bidirectional. [6]

[5] The entire text for this article can be found online at http://java.oreilly.com/news/javaintl_0701.html.

[6] In these languages, text is written from right to left, while numbers and currency are written from left to right.

The example usage of the tag in this article did not elucidate the other looming issue you might be faced with when designing for bidirectional languages. The entire user interface can also be "written" differently. Take Figure 8-5, for example, which shows Microsoft Outlook Express running under a Hebrew version of Windows.

Figure 8-5. Microsoft Outlook Express running under a Hebrew version of Windows
figs/jebp_0805.gif

To accommodate such issues in your web-based applications, develop your user interface through a portal approach . In a portal approach, you identify potential areas of content that need to be displayed to a user. From Figure 8-5, you can discern four distinct content areas:

  1. Menu bar at the top of the screen containing the various menu options and a button bar

  2. Folder list containing the various mail folders for the mailbox(es) that have been set up for Outlook Express

  3. Address book containing the names of contacts for the given user

  4. Content area where information about Outlook Express is displayed, as well as a list of messages and the current message body

In Example 8-3, we have modified the InsertText tag from David's article to implement the LocaleSupport interface (this interface is discussed in the next section). You implement the required getLocale( ) and setLocale( ) methods and initialize the locale attribute to one of the constants defined in this interface. The InsertText custom tag is used to handle the output of localized text from a resource bundle onto a JSP page while taking directionality of the text into account. That is, for certain locales, as in English, the text will be written left to right with the HTML <DIV> tag and its directionality attribute, DIR .

Example 8-3. Adaptation of InsertText JSP custom tag using the LocaleSupport interface
 package com.ora.i18n.jsptags;     import com.ora.i18n.LocaleSupport;     import javax.servlet.jsp.*; import javax.servlet.jsp.tagext.TagSupport; import java.awt.*; import java.io.IOException; import java.util.*;     public class InsertText extends TagSupport implements LocaleSupport {     private Locale locale;     private String textID;     private String resourceBundleName;         private final static String DIV_LTR = "<DIV DIR=\"LTR\">";     private final static String DIV_RTL = "<DIV DIR=\"RTL\">";     private final static String CLOSING_DIV = "</DIV>";         public InsertText(  ) {         locale = LocaleSupport.APPLICATION_DEFAULT_LOCALE;         textID = null;         resourceBundleName = null;     }         public void setLocale(Locale inLocale) {         this.locale = inLocale;     }         public Locale getLocale(  ) {         return locale;     }         public void setTextID(String textID) {         this.textID = textID;     }         public void setResourceBundleName(String resourceBundleName) {         this.resourceBundleName = resourceBundleName;     }         public int doStartTag(  ) throws JspException {         JspWriter out = pageContext.getOut(  );             ResourceBundle rb = ResourceBundle.getBundle(resourceBundleName,                 locale);         try {             ComponentOrientation co =                     ComponentOrientation.getOrientation(locale);             if (co.isLeftToRight(  )                      co.equals(ComponentOrientation.UNKNOWN)) {                 out.print(this.DIV_LTR);             } else {                 out.print(this.DIV_RTL);             }             out.print(rb.getString(textID));             out.print(this.CLOSING_DIV);         } catch (IOException ioe) {             throw new JspTagException(ioe.toString(  ));         } catch (MissingResourceException mre) {             throw new JspTagException(mre.toString(  ));         }         return SKIP_BODY;     }         public void release(  ) {         super.release(  );         locale = LocaleSupport.APPLICATION_DEFAULT_LOCALE;         textID = null;         resourceBundleName = null;     } } 

Example 8-4 is the taglib.tld file used in your web application containing the definition of the InsertText tag and the appropriate tag attributes. Notice that the locale attribute is not a required attribute, as it defaults to the value set from the LocaleSupport interface.

Example 8-4. taglib.tld used in your web application
 <?xml version="1.0"?> <!DOCTYPE taglib PUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.1//EN" "http://java.sun.com/j2ee/dtds/web-jsptaglibrary_1_1.dtd">     <taglib>     <tlibversion>1.0</tlibversion>     <jspversion>1.1</jspversion>     <shortname>oreillytags</shortname>         <tag>         <name>InsertText</name>         <tagclass>com.ora.i18n.jsptags.InsertText</tagclass>         <bodycontent>JSP</bodycontent>         <attribute>             <name>textID</name>             <required>true</required>             <rtexprvalue>true</rtexprvalue>         </attribute>         <attribute>             <name>resourceBundleName</name>             <required>true</required>             <rtexprvalue>true</rtexprvalue>         </attribute>         <attribute>             <name>locale</name>             <required>false</required>             <rtexprvalue>true</rtexprvalue>         </attribute>     </tag>     </taglib> 

In Example 8-5, a simple web.xml file is defined, along with the tag library from Example 8-4.

Example 8-5. web.xml used in your web application
 <?xml version="1.0" encoding="ISO-8859-1"?>     <!DOCTYPE web-app     PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"     "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">     <web-app>       <taglib>     <taglib-uri>/oreilly-taglib</taglib-uri>     <taglib-location>/WEB-INF/META-INF/taglib.tld</taglib-location>   </taglib>     </web-app> 

Example 8-6 shows the JSP page that is used to render Figure 8-6. Note that you set the language locale directly in the user's session.

Example 8-6. Simple JSP template layout using HTML frames to achieve a left-to-right layout (English)
 <%@ page import="java.util.Locale,                  com.ora.i18n.LocaleSupport" %> <%@ page contentType="text/html; charset=UTF-8" %> <%@ page session="true" %> <%@ taglib uri="/oreilly-taglib" prefix="oreillytags"%> <%     Locale userLocale = new Locale("en");     session.setAttribute(LocaleSupport.USER_PREFERRED_LOCALE, userLocale); %>     <html>     <frameset rows="20%, 80%">     <frame src="menu_bar.jsp">     <frameset cols="30%, 70%">         <frame src="navigation_bar.jsp">         <frame src="content.jsp">     </frameset> </frameset>     </html> 

Example 8-7 shows the JSP page that is used to render Figure 8-7. The locale set for the language preference differs from that in Example 8-3 in that you use a locale appropriate for Hebrew. Note that you use the same content "areas": the topmost menu bar, the navigation bar, and the content area. However, in this example, you specify a right-to-left layout, which is appropriate for this locale.

Example 8-7. Simple JSP template layout using HTML frames to achieve a right-to-left layout (Hebrew)
 <%@ page import="java.util.Locale,                  com.ora.i18n.LocaleSupport"%> <%@ page contentType="text/html; charset=UTF-8" %> <%@ page session="true" %> <%@ taglib uri="/oreilly-taglib" prefix="oreillytags"%> <%     Locale userLocale = new Locale("iw");     session.setAttribute(LocaleSupport.USER_PREFERRED_LOCALE, userLocale); %>     <html>     <frameset rows="20%, 80%">     <frame src="menu_bar.jsp">     <frameset cols="70%, 30%">         <frame src="content.jsp">         <frame src="navigation_bar.jsp">     </frameset> </frameset>     </html> 

In Figure 8-6, the content appears in English, and the layout goes from left to right, which is appropriate for this language.

Figure 8-6. Template-based approach to JSP development showing a left-to-right layout
figs/jebp_0806.gif

In contrast to Figure 8-6, Figure 8-7 shows how Example 8-7 is rendered. As you can see from Figure 8-7, the content areas run right to left, as does the content with the individual areas.

Figure 8-7. Template-based approach to JSP development showing a right-to-left layout
figs/jebp_0807.gif

The text resource bundle for English is not given, but Example 8-8 shows, for the sake of simplicity, an untranslated resource bundle used for the Hebrew language. If you were to give a real Hebrew resource bundle, you would of course have the text translated and use the appropriate Unicode characters .

Example 8-8. textresources_iw.properties
 Menu_Bar_Message=Menu bar in Hebrew Navigation_Bar_Message=Navigation bar in Hebrew Content_Area_Message=Content area in Hebrew 

8.2.4 Customize Localization and Data Manipulation Using XML and XSTL

To say that XML is widely becoming a popular data transport in web applications is an understatement. However, some aspects of XML related to internationalization are not necessarily overstated, but can be overlooked. See Example 8-9.

Example 8-9. Header portion of web.xml
 <?xml version="1.0" encoding="ISO-8859-1"?>     <!DOCTYPE web-app     PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"     "http://java.sun.com/j2ee/dtds/web-app_2.2.dtd">     <web-app> </web-app> 

At this point, you probably have zeroed in on the encoding attribute of the XML prolog. In this snippet from a web.xml document, you can see that you are allowed to define the character encoding for the XML document. Example 8-9 specifies the encoding of the document as ISO-8859-1, or Latin-1. Typically, you will see XML documents with an encoding of UTF-8.

This attribute dictates the encoding of all the data in the XML document. Therefore, it affects how your XML parser treats the data. So, if you are writing your own XML documents, you should output the encoding in the XML prolog that is appropriate for the data within the XML document.

For example, suppose that you are passed data from the business object layer in XML that represents a user's order from an online warehouse. Aside from the encoding, how can you display certain data elements appropriate for the user? Well, remember that the overall document and subsequent elements can be tagged with a locale identifier to dictate how certain data will be displayed. Example 8-10 shows how a sample order might look.

Example 8-10. Simplified XML order data
 <?xml version="1.0" encoding="UTF-8"?>     <order-summary> <locale>en_US</locale> <user-id>czarnecki</user-id> <order-total-items>3</order-total-items> <order-total-price>56.78</order-total-price> </order-summary> 

The locale can be used to select the appropriate surrounding text for the order from a resource bundle. It can also be used to display numbers, dates, and times appropriate for the given locale. Business rules might also dictate that certain elements must maintain their own locale attribute. For example, a U.S.-based web site might want to display catalog item prices in Japanese Yen for Japanese customers.

If you are dealing with large amounts of XML that you need to turn into another presentation format (e.g., HTML), you might want to investigate the Cocoon web-publishing framework from the Apache project. [7] Cocoon is a very sophisticated framework that addresses internationalization and localization requirements for applications, in large part through the I18nTransformer class. Cocoon is very easy to set up and use. [8] We leave further investigation of Cocoon up to you, but we would like to show you some screenshots of the internationalization example included with Cocoon to demonstrate the power and flexibility it offers.

[7] Cocoon is available at http://xml.apache.org.

[8] We set up Cocoon 2.0.2 using Tomcat 3.3.1 and the Java 2 SDK 1.3.1_01.

Figure 8-8 shows the simple internationalization example from Cocoon with U.S. English as the selected language.

Figure 8-8. Simple internationalization running in U.S. English
figs/jebp_0808.gif

Figure 8-9 shows the sample example, but with UK English as the selected language.

Figure 8-9. Simple internationalization running in UK English
figs/jebp_0809.gif

As you can see in Figure 8-9, the date and time at the top of the page are different from those in Figure 8-8. The date, time, and currency at the bottom of the page are also formatted appropriately for UK English.

I l @ ve RuBoard


The OReilly Java Authors - JavaT Enterprise Best Practices
The OReilly Java Authors - JavaT Enterprise Best Practices
ISBN: N/A
EAN: N/A
Year: 2002
Pages: 96

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