Programming Tutorials

ActionErrors and ActionError in Struts

By: Abinaya in Struts Tutorials on 2007-10-01  

Struts request handling lifecycle as a happy day scenario is from the point the user submits an html form till the user sees the next page. In reality, users of your web application may submit incorrect data or sometimes no data at all. You have to catch these as close to the user interface as possible, rather than waiting for the middle tier or the database to tell you that a column cannot be inserted in the database because it was expecting a non-null value. There are two consequences of such programming practice.

  1. Server time and resources are precious since they are shared. Spending too much of server’s time and resources on a request, that we know is going to fail eventually is a waste of server resources.
  2. It has a negative impact on the code quality. Since one has to prepare for the possibility of having null data, appropriate checks have to be put (or NumberFormatExceptions have to be caught) everywhere in the code.

Generally business logic is the toughest code of the system and contains enough if-else blocks as such. More if-else blocks for null checks can only mean two things bad code and maintenance nightmare. Not an elegant programming to say the least. If only you could verify the validity of the user data as close to the user, then the rest of the code only has to deal with business logic and not invalid data.

//validate() method in the CustomerForm
public ActionErrors validate(ActionMapping mapping, HttpServletRequest request)
{
    // Perform validator framework validations
    ActionErrors errors = super.validate(mapping, request);
    // Only need crossfield validations here
    if (parent == null) {
        errors.add(GLOBAL_ERROR, new ActionError("error.custform"));
    }
    if (firstName == null) {
        errors.add("firstName", new ActionError("error.firstName.null"));
    }
return errors;
}

Struts provides validate() method in the ActionForm to deal with user input validations. Let us now look at how you can validate the user input and report errors to the framework.

The validate() method is called after the ActionForm instance is populated with the form data. A sample validate() method is shown above. In the validate() method, you will notice an object called ActionErrors is instantiated. All error checks are performed with the usual if-else blocks. If there are errors, then an individual ActionError object is created for the culprit field and added to the ActionErrors. Think of ActionErrors as a Map for the individual ActionError objects. You can associate one or more ActionError objects for each key. The form field name is generally chosen as the key and can have multiple ActionError objects associated with it. The ActionError is either specific to a field in the ActionForm or it is global to the entire form. When the error is specific to a form field, the field name is used as the key in the ActionErrors. When the error is global to the form, the key name is always GLOBAL_ERRORS. Both of the cases are shown in the Listing above.

You might also notice that the ActionError constructor takes a rather cryptic key as the argument. This key is declared in a properties file whose value is the actual error message. The properties file is selected based on the user chosen Locale. The technical term for this properties file where the messages are externalized is Message Resource Bundle. It is based on the Java's concept of Localization using the java.util.ResourceBundle and has a whole lot of bells and whistles. The properties file also serves another purpose apart from Localization. It lets you change the messages without recompiling the code, and is quite handy while maintaining the code. An entry in the Message Resource Bundle properties file looks like:

error.firstName.null=First Name cannot be null

The RequestProcessor stops any further processing when it gets the ActionErrors object with ActionError objects. The Action instance never gets the control (and never gets a chance to return ActionForward). Hence the RequestProcessor consults the ActionMapping object to find the page to be displayed. Notice that the ActionMapping has an attribute named "input". This attribute specifies the physical page to which the request has to be forwarded on error. Generally this page is the original page where user entered the data since it is natural that user would want to reenter the data in the same page on error and resubmit.






Add Comment

* Required information
1000

Comments

No comments yet. Be the first!

Most Viewed Articles (in Struts )

Latest Articles (in Struts)