Programming Jakarta Struts, 2nd Edition [Electronic resources] نسخه متنی

اینجــــا یک کتابخانه دیجیتالی است

با بیش از 100000 منبع الکترونیکی رایگان به زبان فارسی ، عربی و انگلیسی

Programming Jakarta Struts, 2nd Edition [Electronic resources] - نسخه متنی

Chuck Cavaness

| نمايش فراداده ، افزودن یک نقد و بررسی
افزودن به کتابخانه شخصی
ارسال به دوستان
جستجو در متن کتاب
بیشتر
تنظیمات قلم

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

روز نیمروز شب
جستجو در لغت نامه
بیشتر
لیست موضوعات
توضیحات
افزودن یادداشت جدید








12.3 Internationalizing Your Struts Applications


The internationalization support provided by the Struts framework
focuses almost exclusively on the presentation of text and images for
the application. Functionality such as accepting input from
nontraditional languages is not covered within the Struts framework.

As you've already seen, depending on your Struts
configuration settings, the framework can determine the preferred
locale for a user and store it into the user's
session. Once the user's locale has been determined,
Struts can use this locale to look up text and other resources from
the resource bundles. The resource bundles
are essential components in the Struts framework.


12.3.1 The Struts Resource Bundle


As you saw in Chapter 4, each of your
application modules can be configured with one or more resource
bundles. The information within each bundle is available to actions,
action forms, JSP pages, and custom tags alike.


12.3.1.1 Creating a Struts resource bundle

Resource bundles that you create must
follow the conventions of the
PropertyResourceBundle class from the Java core
library. That is, you need to create a text file for your resource
bundle that has a .properties extension and that
adheres to the guidelines discussed in the JavaDoc for the
java.util.Properties class. The most important of
these guidelines is that the format of the messages within this file
is:

key=value

Example 12-3 displays a properties file called
StorefrontMessageResources.properties that can
be loaded by the Struts framework.


Example 12-3. A simple Struts resource bundle

global.title=Virtual Shopping with Struts
global.error.invalidlogin=The login was unsuccessful! Please try again.
global.required={0} is a required value.
label.featuredproducts=This Weeks Featured Products
label.email=Email Address
label.password=Password
label.returning
label.firstName=First Name
label.lastName=Last Name
label.address=Address
label.city=City
label.state=State
label.postalCode=Postal Code
label.zip=Zip
label.country=Country
label.phone=Phone
button.add=Add Me
button.delete=Delete
button.checkout=Checkout
button.saveorder=Save Order
errors.required={0} is required.
errors.minlength={0} can not be less than {1} characters.
errors.maxlength={0} can not be greater than {1} characters.
errors.invalid={0} is invalid.
errors.byte={0} must be a byte.
errors.short={0} must be a short.
errors.integer={0} must be an integer.
errors.long={0} must be a long.
errors.float={0} must be a float.
errors.double={0} must be a double.
errors.date={0} is not a date.
errors.range={0} is not in the range {1} through {2}.
errors.creditcard={0} is not a valid credit card number.
errors.email={0} is not a valid e-mail address.

You must be sure to name the message resource file with the extension
.properties, or the Struts framework will not be
able to load it.


Notice that the keys used in Example 12-3 are
separated by a period (.). We could have used other characters in the
keys, or we could have used a single-word key like
labelPhone=Phone. Using namespacing in your keys
is a great way to organize the localized text to make maintenance
easier and to prevent name collisions. This is similar to how Java
classes use package names.

You have to be careful, however, when using characters other than the
period as a separator. The colon (:), for example, can be used
instead of the equals sign (=) to separate the key and the value, and
it will cause problems if you use it within your keys. If you
don't want to use the period character in your keys,
you can safely use the underscore or the hyphen character. Spaces are
not a good choice, as they will also cause problems.


12.3.1.2 Resource bundle naming guidelines

The naming of the resource bundle
is critical to it working properly. All resource bundles have a base
name that you select. In Example 12-3, the name
StorefrontMessageResources was used as a base
name. If you needed to provide an additional localized resource
bundle for the French language and the country Canada, you would
create a properties file called
StorefrontResouces_fr_CA.properties with the
appropriate localized resources.

When the Struts framework searches for a message from one of the
bundles, it looks for a bundle that is the closest match, based on
the base name and the locale. If no locale is provided, it will use
the default locale. Only when it fails to find a resource bundle with
a specific language and country code as part of the name will it
default to the base resource bundle. The base resource bundle is the
one without any language or country code in its name.


You should always provide a base resource bundle. If a user with a
locale that you don't support visits your site, the
application will select the base bundle for that user.


12.3.1.3 The resource bundle and the classpath

The resource bundle needs to be placed in a
location where it can be found and loaded. This means that the same
class loader that loads the web application must also be able to
locate and load the resource bundle. For web applications, the
appropriate location is the WEB-INF/classes
directory.

If you provide a package name for the resource bundle, it must reside
in the correct package as well. For example, if you name your
resource bundle com.oreilly.struts.
StorefrontResources.properties
, you must place it into the
WEB-INF/classes/com/ oreilly/struts directory.


12.3.2 Accessing the Resource Bundle


The
resource
bundles for a Struts application are loaded at startup, and each
bundle is represented in memory by an instance of the
org.apache.struts.util.
MessageResources class (actually by its concrete
subclass, PropertyMessageResources).

Each MessageResources instance is stored in the
ServletContext when the application is initialized
and can be accessed from just about any component within the servlet
container. However, you'll more typically use a
combination of the custom tags and the
ActionMessage or ActionError
classes to access the resources, rather than calling methods on the
MessageResources class directly. In fact, if you
use a combination of the declarative exception handling discussed in
Chapter 10 and the Validator framework from
Chapter 11, it's possible that
you won't have to create
ActionMessage or ActionError
instances at all; the framework will do it for you automatically.

If you need to create an ActionMessage or
ActionError manually, however, you can. From the
validate() method of an
ActionForm, it would look something like this:

public ActionErrors validate(ActionMapping mapping, HttpServletRequest request){
ActionErrors errors = new ActionErrors( );
if(getEmail( ) == null || getEmail( ).length( ) < 1) {
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("security.error.email.required"));
}
if(getPassword( ) == null || getPassword( ).length( ) < 1) {
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("security.error.password.required"));
}
return errors;
}

The String argument passed into the constructor of
the ActionError class must be a key in the
resource bundle. The ActionMessage and
ActionError classes have several constructors,
most of which allow you to pass in substitution arguments, for when
your messages are compound messages, as explained earlier in this
chapter. You can also create ActionMessages and
ActionErrors from an Action
class. The following is a small fragment from the Storefront
LoginAction class:

// Log in through the security service
IStorefrontService serviceImpl = getStorefrontService( );
String errorMsg = null;
UserView userView = null;
try{
// Attempt to authenticate the user
userView = serviceImpl.authenticate(email, password);
}catch( InvalidLoginException ex ){
ActionErrors errors = new ActionErrors( );
ActionError newError = new ActionError("error.security.invalidlogin");
errors.add( ActionErrors.GLOBAL_ERROR, newError );
saveErrors( request, errors );
return mapping.findForward( IConstants.FAILURE_KEY );
}catch( ExpiredPasswordException ex ){
ActionErrors errors = new ActionErrors( );
ActionError newError = new ActionError("error.security.passwordexpired");
errors.add( ActionErrors.GLOBAL_ERROR, newError );
saveErrors( request, errors );
return mapping.findForward( IConstants.FAILURE_KEY );
}catch (AccountLockedException ex){
ActionErrors errors = new ActionErrors( );
ActionError newError = new ActionError("error.security.accountlocked" );
errors.add( ActionErrors.GLOBAL_ERROR, newError );
saveErrors( request, errors );
return mapping.findForward( IConstants.FAILURE_KEY );
}

This fragment is another reason why the declarative
exception-handling feature of Struts is so attractive. Look at the
amount of work that we did here. With declarative exception handling,
all of this would be defined within the Struts configuration file.


12.3.2.1 The Bean tag library's MessageTag class

The Struts framework contains several custom tags that can be used in
conjunction with the MessageResources for an
application. One of the most important, however, is the
Message tag that is part of the
Bean tag library.

This custom tag retrieves a message string from one of the bundles
for an application. It supports optional parametric replacement if
the JSP page requires it. All you need to do is provide the key from
the bundle and specify which application bundle to use, and the tag
will write out the information to the JSP page. For example, the
following JSP fragment uses the MessageTag to
write out the title of the HTML page:

<head>
<title><bean:message key="global.title"/></title>
</head>

You'll use this tag quite often within your Struts
applications.


12.3.3 Setting the Character Set


Supporting
character sets other than the
typical U.S. default ISO-8859-1 is a little tricky. There are several
steps that you must perform before your environment will be prepared
to support them. First, you need to configure the application server
and/ or servlet container to support the
character-encoding scheme that you want
to use. For example, for Unicode you would tell the container to
interpret input as UTF-8. Check with the vendor's
documentation, as each one will be configured differently. You can
also set up a servlet filter to do this, but this requires a
container that supports the 2.3 Servlet API.

Next, the contentType property within the
controller element in the Struts configuration
file needs to be set correctly. Set it to
text/html;charset=UTF-8 for HTML Unicode support.
You can also specify this in the JSP pages by putting the following
line at the top of each page:

<%@ page contentType="text/html; charset=utf-8" %>

and this line in the HTML head section:

<head>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=UTF-8">
</head>

Another option is to set the content type and encoding scheme in the
response object, like this:

response.setContentType("text/html; charset=UTF-8");

However, you might have to do this in several different places,
making maintenance and customization more difficult.

You may also have to tell the browser to always send URLs as UTF-8.
There's usually a checkbox or option to do
thisin IE 5.5, it's in the advanced options
section.

There are two final steps to ensure that your application can fully
support Unicode. The first is to make sure your database is
configured for Unicode. This is usually the default, but you should
verify that this is the case. Second, if you're
using the JRE rather than the SDK, use the I18N version and not the
U.S. version.


    / 181