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

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

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

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

Chuck Cavaness

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

فونت

اندازه قلم

+ - پیش فرض

حالت نمایش

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








7.3 Using ActionErrors


Earlier in this chapter in Example 7-2, we saw that
the validate() method returns an ActionErrors object.
The ActionErrors class encapsulates one or more
errors that have been discovered by the application. Each problem
discovered is represented by an instance of
org.apache.struts.action.ActionError.


It should be pointed out that in Example 7-2,
instances of the ActionMessage class and not
ActionError were added to the
ActionErrors collection.
ActionMessage is actually the parent of
ActionError. We will talk more about the usage of
the ActionMessage class in the next section. For
now, when you see ActionError mentioned, just know
that you can substitute ActionMessage in most
cases.

An ActionErrors object has request scope. Once an
instance is created and populated by the validate(
)
method, it is stored into the request. Later, the JSP
page can retrieve the object from the request and use the
ActionError objects contained within it to display
error messages to the user.


The Struts framework includes several JSP custom tags that make
retrieving and displaying the
messages
very easy. Two of them, ErrorsTag and
MessagesTag, are discussed in Chapter 8.

An instance of ActionErrors can be instantiated in
the validate() method and populated by adding
instances of the ActionMessage class to it. The
LoginForm from Example 7-2
demonstrated this and is illustrated again here for convenience:

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

The validate() method in this fragment checks to
make sure that the email and password fields have been set with
values other than an empty string. If not,
ActionMessage objects are added to the
ActionErrors instance.

The ActionMessage class contains several useful
constructors; a few are listed here:

public ActionError(String key);
public ActionError(String key, Object value0);
public ActionError(String key, Object value0, Object value1);
public ActionError(String key, Object[] values);

The key argument is a String value that
corresponds to a key from one of the application's
resource bundles. The custom tags MessagesTag and
ErrorsTag use this value to look up the message to
display to the user. The remaining arguments are used as parametric
replacement values for the message. For example, if you had a bundle
message defined like this:

global.error.login.requiredfield=The {0} field is required for login

you could create an instance of an ActionMessage
like this:

ActionMessage message = new ActionMessage("global.error.login.requiredfield", "Email");

The message displayed to the user after substituting in the
"Email" string would be:

The Email field is required for login


If building
I18N
applications is a requirement for you, you must be careful when using
hardcoded String values, as in the previous
example. The string "Email"
can't easily be localized, because
it's hardcoded into the source code.

In this case, you should get the localized value from the bundle as
well before passing it as an argument in the
ActionMessage constructor.

When adding instances of the ActionMessage class
to the ActionErrors object, the first argument in
the add() method is a property that can be used
to retrieve a specific ActionMessage instance. For
example, if you have a login input field and a password field and you
want to display a particular message next to each corresponding
field, you could do:

errors.add("login",
new ActionMessage("security.error.login.required"));
errors.add("password",
new ActionMessage ("security.error.password.required"));

By associating a specific name with each error, you can retrieve the
respective error in the JSP page using the
MessagesTag tag, which we'll
discuss in the next chapter.

If instead you want to show all of the errors at the top of the page,
you can use the constant
ActionMessages.GLOBAL_MESSAGE, like this:

errors.add(ActionMessages.GLOBAL_MESSAGE,
new ActionMessage("security.error.password.required"));


7.3.1 The ActionMessage Class


In Struts 1.1, a new message class was added that also can be used to
display messages to a user. The
org.apache.struts.action.ActionMessage class
operates in the same manner that the ActionError
class doesin fact, it was added as the superclass to the
ActionError class.

The main reason that the
ActionMessage class was
added to the framework was that the name
ActionError implies that it
shouldn't be used for general-purpose informational
or warning messages, although it is used that way by many developers.
A more general-purpose message class made sense.

The ActionMessage is used exactly like the
ActionError class, except that it can represent a
less severe message that needs to be displayed to the user. Instances
of this class are created the same way and added to an
ActionMessages object instead of an
ActionErrors object. Because
ActionError is just a specialized message, it
extends the ActionMessage class. Figure 7-5 illustrates the relationship between these
classes.


Figure 7-5. ActionErrors are specialized ActionMessages


Starting with Struts 1.2, you should expect the
ActionError class to be deprecated. You should
make all attempts to start using the ActionMessage
class instead. The ActionErrors class will a
little harder for the Struts developers to remove as it is tied into
the framework quite tightly. Nonetheless, the writing is on the wall
and you may eventually be using ActionMessages
exclusively.


7.3.2 Creating ActionErrors in the Action Class


The ActionForm is not the only place that you can
create ActionMessages or
ActionErrors. You also can create them in other
parts of the framework. If, for example, a business operation called
from an Action raised an exception and you wanted
to insert an error message informing the user, you could create an
ActionMessage from the Action
class itself. The Struts Action class includes
functionality to support this.

When the business operation throws the exception, the
Action class catches it and takes the appropriate
stepsusually returning to the previous page and displaying an
error message to the user. Returning to the previous state can be
accomplished by returning the appropriate
ActionForward, but the
ActionMessage needs to be put in the request
before the forward occurs.


In Chapter 10, you'll learn how
to take advantage of the declarative exception handling in Struts 1.1
and thus avoid having to deal with the exceptions in the
Action class completely.

Example 7-4 illustrates how to put the
ActionMessage into
the request using the LoginAction class.


Example 7-4. Creating ActionErrors from the execute( ) method

public ActionForward execute( ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response )
throws Exception{
/**
* Get the user's email and password, which should already have been
* validated by the ActionForm.
*/
String email = ((LoginForm)form).getEmail( );
String password = ((LoginForm)form).getPassword( );
// Log in through the security service
IStorefrontService serviceImpl = getStorefrontService( );
UserView userView = null;
try{
userView = serviceImpl.authenticate(email, password);
}catch( InvalidLoginException ex ){
ActionMessages messages = new ActionMessages( );
ActionMessage newMessage = new ActionMessage ( "security.login.failed" );
messages.add(ActionMessages.GLOBAL_MESSAGE, newMessage);
saveMessages( request, messages );
// Return back to the previous state
return mapping.findForward( mapping.getInput( ) );
}
// Authenticate was successful
UserContainer existingContainer = null;
HttpSession session = request.getSession(false);
if ( session != null ){
existingContainer = getUserContainer(request);
session.invalidate( );
}else{
existingContainer = new UserContainer( );
}
// Create a new session for the user
session = request.getSession(true);
existingContainer.setUserView(userView);
session.setAttribute(IConstants.USER_CONTAINER_KEY, existingContainer);
return mapping.findForward(IConstants.SUCCESS_KEY);
}

In Example 7-4, when an
InvalidLoginException is thrown by the
authenticate() method, the exception is caught
and an ActionMessage is created. The
saveMessages() method exists in the Struts base
Action class and stores the
ActionMessages object into the request.

Once the ActionError or
ActionMessage is stored in the request and control
is forwarded to a JSP page, one of the framework's
JSP custom tags can be used to print out the messages to the user.
These tags are discussed in the next chapter.


    / 181