Editor's Note: This is part two of a two-part series on Jakarta Struts 1.1. The first part is available here. Portions of this article are excerpted from Sue Spielman's book, The Struts Framework: Practical Guide for Java Programmers (Morgan-Kaufmann), one of the first books on the market covering Struts 1.1 in detail. You can reach Sue at .
Nested Tag Library
The whole point of having nested tags is that the tags can relate to each other and describe the structure of the model they're managing. The assumptions made by the tags simplify the necessary coding. Struts 1.0 developers can heave a sigh of relief knowing that they won't have to mangle code any longer to render a display of a list within a list.
The Struts nested tag library was introduced in Struts 1.1. Almost all of the tags in this library extend the base Struts tags that we've already talked about. This includes tags from the
Logic libraries, except they are prefixed with a nested namespace. So, for example, if we are nesting an
<html:link> tag, we would use
<nested:link> instead. There are also tags new to the nested tag library. The new tags include
<nested:root> tag is used to indicate that you are starting a nested scope. This tag is used if
<html:form> is not being used. The
<html:form> (for backwards compatibility) or
<nested:form> tags will automatically start a scope for you.
The difference between using non-nested tags as opposed to those from the nested library is that using the nested version allows the tags to relate to each other in a nested hierarchy. The fundamental logic of the original tags doesn't change, except that all references to beans and bean properties will be managed in a nested context using the dot notation that we have already seen when using properties. When building complex pages, it is highly likely that you will want to use the nested features. This makes pages much easier to write and maintain, since it allows for the logical flow to be maintained without having to do work-arounds, as was required before the 1.1 release.
The Validator framework is now part of the Struts package structure and can be found in
org.apache.struts.validator. Why use the Validator framework? Validator makes life a bit easier when you have to deal with required fields; determining matches to a regular expression; email, credit card, and date validation; and server-side type checking.
This framework is based on the Commons Validator that can be found at jakarta.apache.org/commons.
The purpose is to perform server-side validations based on validation rules located in validation.xml. It is possible to add custom validations to this file. Rules can be defined for different locales. It's possible to store your specific Validator rules in a separate file. This is accomplished by setting the
config-rules parameter in the
ValidatorServlet contained in the web.xml file. The standard file is available in the Struts dist directory and is called validator-rules.xml.
Using this framework requires adding the
ValidatorServlet to your web.xml file with its appropriate configuration parameters and then extending
org.apache.struts.validator.action.ValidatorForm instead of
Validator is the first component to implement the new
PlugIn interface in Struts 1.1, which we'll talk about next.
You can also add pluggable Validators by adding a validation method signature to your
ValidatorAction class. For more details, see the
A new feature of Struts 1.1 is the ablity to define a
PlugIn is a configuration wrapper for an application-specific module or service that must be notified about application startup and application shutdown events. These events correspond to the container calls
destroy() on the corresponding
ActionServlet instance, which allows a module to be called without the need to subclass
ActionServlet for simple
Servlet lifecycle activities.
PlugIn modules can be configured in the struts-config.xml file, using the
<plug-in> element. Classes that implement the
PlugIn interface must supply a zero-argument constructor for use by
ActionServlet. Configuration can be accomplished by providing standard
JavaBeans property setter methods that will all have been called before the
init() method was invoked. An instance of the specified class is created for each element, and can be configured with nested
set-property elements. For example, in struts-config.xml we might have the last entry defined as:
<plug-in className="org.apache.struts.validator.action.ValidatorPlugIn"> <set-property property="pathname" value="/WEB-INF/validator-rules.xml"/> <set-property property="pathname" value="/WEB-INF/validation.xml"/> </plug-in>
This means that two instances of the
ValidatorPlugIn will be created, each setting the property pathname to the appropriate value. By supporting the
destroy() methods of
ValidatorPlugin is notified about application startup and shutdown events without having to be concerned with extending
PlugIns are configured in the struts-config.xml file by setting the
Declarative Exception Handling
Declarative exception handling allows for Actions to propagate exceptions. This feature is the very reason that the
perform() method signature changed from throwing
ServletException to just
Exception. This is also why we see the
execute() method of an Action called by the
ActionServlet. One reason for going this route is so your Actions don't have to think about each and every exception that might be thrown from your business logic. It also allows exceptions to be configured within the struts-config.xml file.
Declarative exception handling is accomplished in two ways. One is by configuring
<global-exceptions> in the struts-config.xml file. The other is by using the
exception element of
<action>, which describes a mapping of an exception that may occur during Action delegation.
The way that the exceptions are declared is very similar to the way that
<forwards> are declared. A
<global-exceptions> configures the global handling of exceptions thrown by Actions to mappable resources using an application-relative URI path. This can be a specific page designed to handle this exception.
It is also possible to override an exception handler declared in the global setting by using the exception element in the action, which uses the same type attribute as defined in the global setting. You can specify the
className attribute, which indicates the implementation subclass of the standard configuration bean. The default class is:
The handler attribute is the fully-qualified Java class name of the exception handler that should handle this exception. The default is
key attribute is the message resources key specifying the error message associated with this exception. This is helpful in keeping your errors friendly when your application is internationalized.
Pages: 1, 2