In addition to Struts' core JSP tag libraries-Bean, HTML, and Logic-Struts provides an advanced tag library called Nested that can be used to enhance and simplify JSP development. The Nested Tag Library extends several tags from the Bean, HTML, and Logic Tag Libraries, giving them the ability to work in a nested context. The Nested Tag Library was initially created by Arron Bates as an extension to Struts to fill what he saw as a void in the way many of the tags worked in the existing libraries. As his library became popular, it was later integrated into the core Struts framework during the 1.1 release cycle.
The best way to understand the importance of the Nested Tag Library is to begin by reviewing the way nested objects work without it. By default, each of the tags (hereafter referred to as the base tags) extended by the Nested Tag Library supports the notion of objects nested within other objects. That is, the base tags can access properties of one object nested inside another to any arbitrary level. For example, an Employee object might have a nested Address object, and the Address object may have several fields, such as Line 1, Line 2, City, State, and Zip. To access an Employee object named "employee" with a nested Address object named "address" whose State field is named "state" with the base Struts tags, you would specify the field as "employee.address.state", as shown in the following example:
Struts uses reflection to access the state field. Each level of the nested hierarchy is traversed by calling a getter method for that level's field; thus, in the preceding example, Struts uses reflection to call getAddress( ) on the employee object and getState( ) on the address object.
Although the default method of specifying nested references for fields is very useful and greatly simplifies JSP development, it can be problematic for two reasons:
If an object in a nested hierarchy has its name changed, each nested reference has to be updated. For example, if an Employee object had a nested Address object named "address" that later becomes "homeAddress", every nested reference that refers to fields in the Address object has to be updated to access the fields as "employee .homeAddress.state" instead of "employee.address.state". This is not a huge problem, but it is both time-consuming and error-prone.
When you are working with a nested object that has several fields, you have to type out the entire nested hierarchy for each field over and over. For example, you have to type "employee.address.line1", "employee.address.line2", "employee.address .city", and so on. Again, this is not a major problem, but it is tedious and is a potential source of errors.
Fortunately, the Nested Tag Library eliminates both problems associated with the default approach to nested tags. The Nested Tag Library allows you to define logical nesting levels and then associate objects with them so that all tags nested inside a level are relative to that level. Therefore, instead of fully qualifying a nested reference within each level of the object hierarchy, you can use the Nested Tag Library's nest tag to define each level of the hierarchy. Within each level, you specify the property that you're interested in along with any other tags you need. Here is an example:
<nested:nest property="employee"> <nested:nest property="address"> Line 1: <nested:text property="line1"/> Line 2: <nested:text property="line2"/> City: <nested:text property="city"/> State: <nested:text property="state"/> Zip: <nested:text property="zip"/> </nested:nest> </nested:nest>
Notice that the Nested Tag Library's text tag was used instead of the HTML Tag Library's text tag. The reason is that the base tags are not designed to work with the Nested Tag Library's nesting features. Instead, you must use the Nested Tag Library's extensions to the base tags.
To best understand the benefits of the Nested Tag Library, here is the same example coded without use of the Nested Tag Library:
Line 1: <html:text property="employee.address.line1"/> Line 2: <html:text property="employee.address.line2"/> City: <html:text property="employee.address.city"/> State: <html:text property="employee.address.state"/> Zip: <html:text property="employee.address.zip"/>
As you can see, specifying nested properties without the Nested Tag Library results in more verbose JSP code, which increases the chance for error and the potential for a great deal of maintenance work should the nesting hierarchy change.