As mentioned in Rendering Components for Selecting Multiple Values (page 349), data and messages in the Duke's Bookstore application have been localized for French, German, Spanish, and American English. This section explains how to produce the localized error messages as well as how to localize dynamic data and messages. Rendering Components for Selecting Multiple Values (page 349) describes how page authors access localized data from the page. If you are not familiar with the basics of localizing web applications, see Chapter 14. Creating a Resource BundleA ResourceBundle contains a set of localized messages. To learn how to create a ResourceBundle, see http://java.sun.com/docs/books/tutorial/i18n/index.html After you create the ResourceBundle, put it in the same directory as your classes. Much of the data for the Duke's Bookstore application is stored in a ResourceBundle called BookstoreMessages, located in <INSTALL>/javaeetutorial5/examples/web/bookstore/src/java/com/sun/bookstore/messages/. Localizing Dynamic DataThe Duke's Bookstore application has some data that is set dynamically in backing beans. Because of this, the beans must load the localized data themselves; the data can't be loaded from the page. The message method in AbstractBean is a general-purpose method that looks up localized data used in the backing beans: protected void message(String clientId, String key) { // Look up the requested message text String text = null; try { ResourceBundle bundle = ResourceBundle.getBundle("messages.BookstoreMessages", context().getViewRoot().getLocale()); text = bundle.getString(key); } catch (Exception e) { text = "???" + key + "???"; } // Construct and add a FacesMessage containing it context().addMessage(clientId, new FacesMessage(text)); } This method gets the current locale from the UIViewRoot instance of the current request and loads the localized data for the messages using the getBundle method, passing in the path to the ResourceBundle and the current locale. The other backing beans call this method by using the key to the message that they are trying to retrieve from the resource bundle. Here is a call to the message method from ShowCartBean: message(null, "Quantities Updated"); Localizing MessagesThe JavaServer Faces API provides two ways to create messages from a resource bundle:
Registering Custom Error Messages (page 470) includes an example of registering a ResourceBundle in the application configuration resource file. Creating a Message with a Message FactoryTo use a message factory to create a message, follow these steps:
Implementing the Validator Interface (page 412) gives an example of accessing messages. Using FacesMessage to Create a MessageInstead of registering messages in the application configuration resource file, you can access the ResourceBundle directly from the code. The validateEmail method from the Coffee Break example does this: ... String message = ""; ... message = CoffeeBreakBean.loadErrorMessage(context, CoffeeBreakBean.CB_RESOURCE_BUNDLE_NAME, "EMailError"); context.addMessage(toValidate.getClientId(context), new FacesMessage(message)); ... These lines also call the loadErrorMessage to get the message from the ResourceBundle. Here is the loadErrorMessage method from CoffeeBreakBean: public static String loadErrorMessage(FacesContext context, String basename, String key) { if ( bundle == null ) { try { bundle = ResourceBundle.getBundle(basename, context.getViewRoot().getLocale()); } catch (Exception e) { return null; } } return bundle.getString(key); } |