ONJava.com    
 Published on ONJava.com (http://www.onjava.com/)
 http://www.onjava.com/pub/a/onjava/pub/a/2002/11/06/struts1.html
 See this if you're having trouble printing code examples


JSP and Servlets Learning the New Jakarta Struts 1.1, Part 1

by Sue Spielman
11/06/2002

Editor's Note: This is part one of a two-part article on Jakarta Struts 1.1. 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 .

Over the last year, the Struts framework, a Jakarta open source project, has become practically the de facto standard for building Web applications. Based on the MVC architecture, Struts has proven to be a solid framework that can be used on systems of all sizes. In fact, I’d be hard-pressed to come up with a reason why you and your development team should spend cycles developing a custom MVC framework for a project. It just doesn’t make sense.

Struts v1.1 is the latest version of the framework. While in beta 2 at the time of this writing, it should shortly be in final release. There is no reason, however, why you can’t start using v1.1 today; in fact there are many reasons why you should.

There are two parts to this article. In this first part, we'll cover integration of Jakarta common libraries and multiple application support. The second part will hit the nested tag library, the plug-in API, and declarative exception handling. There have been some significant improvements to the framework, and chances are that you’ll want to start new development with this release. In fact, I would highly recommend doing just that. It has always been a goal of the committers on the Struts project to maintain backwards compatibility with v1.0.2, and they have done an excellent job in the v1.1 release. The last section of this article will point out some things to consider if you're upgrading from v1.0.2 applications to v1.1.

This article is not a Struts primer. It assumes you are familiar with the various components in the architecture. If you need a primer, visit my three-part introduction to the Struts framework.

Related Reading

Programming Jakarta Struts

Programming Jakarta Struts
By Chuck Cavaness

Table of Contents
Index
Sample Chapter

Read Online--Safari Search this book on Safari:
 

Code Fragments only

What's New

There have been some exciting features and improvements made to Struts over the course of the v1.1 development. We’ll talk about each of these in turn, but let’s see what is on the plate.

Let’s look at each feature in turn.

Integration of Jakarta Commons libraries

The Struts utilities package helped solve problems that pop up over and over when building Web applications. Most of the classes in this package do not rely on the controller Servlet framework or the custom tag libraries, so they can be used in general Java application programming. As of Struts 1.1, many of the classes in this package were moved into the Jakarta Commons project. These include the Bean Utilities, Collections, and Digester packages. The logging provided in Struts actually comes from the Commons project as well.

org.apache.commons.beanutils components provide wrappers around the Java Reflection and Introspection APIs. By using classes in the Beanutils package, it is possible to access getter and setter methods dynamically without compiled-in knowledge of the method names. These classes are used with the custom tag libraries of Struts, so it makes sense that if you are writing additional custom tags for your application, you might want to look further into what is available in this package. Table 1 gives you a sense of what is available.

Table 1. Commons Packages Used in Struts 1.1

BeanUtils Populates JavaBeans properties via reflection.
ConvertUtils Converts String values to objects of the specified class.
MappedPropertyDescriptor Describes one mapped property.
MethodUtils Focuses on methods in general rather than properties in particular.
PropertyUtils Uses Java Reflection APIs to allow for generic property getter and setter operations.

The Digester package provides rules-based processing of XML documents. This is great for reading configuration files so that Objects can be initialized correctly. What makes this package useful is that you can do many of the things fairly simply that would otherwise require more in-depth knowledge of DOM or SAX processing. This is accomplished by having a Java object-mapping module that allows specifying rules when patterns in the XML are recognized. There are a number of advanced features available when using a Digester. These include the ability to plug in your own pattern-matching engine, namespace-aware processing, and the creation of RuleSets that encapsulate Rules to be used in multiple applications. If you are explicitly reading any XML files into your applications and need to map them to the appropriate Java Objects, the Digester is quite useful.

DynaActionForms

DynaActionForms provide a convenient mechanism that eliminates the need to write ActionForms at all. DynaActionForm allows for form properties to be dynamic. What this means is that you can define properties in your struts-config.xml file and set the type of the form to be org.apache.struts.action.DynaActionForm. Nothing more needs to be written. DynaActionForms accomplish this by making use of the DynaBean provided in the Apache Commons project. This dynamic behavior is provided through reflection and Hashmaps.

A DynaActionForm is defined in the struts-config.xml using the <form-bean> and <form-property> elements as follows:

<form-bean name="insertDynaForm" type="org.apache.struts.action.DynaActionForm">
    <form-property name="artist" type="java.lang.String"/>
    <form-property name="title" type="java.lang.String"/>
    <form-property name="genre" initial=”Dance” type="java.lang.String"/>
</form-bean>

The attributes of a dynamic form are similar to those of a standard ActionForm. The name is used to reference this form bean in Actions, and the type specifies the class to be instantiated. When using the DynaActionForm class, the dynamic attribute of the <form-bean> automatically defaults to true. For a DynaActionForm, you specify all of the properties of the form by using the <form-property> element. The name is the property name. The type is the fully qualified Java class name of the implementation class of this bean property. If this is an indexed property, you can follow the type with []. You’ll notice that in the last <form-property> defining the genre property, we are setting the initial (or default) value to be "Dance." This value is also used when the reset() method is called on a DynaActionForm, and allows for a mechanism to specify default values on the form. If nothing is specified in the initial attribute, then all primitive types are set to zero, while Objects are set to null.

It can be very convenient to use DynaActionForm. One of the main advantages is that you have to write less code. What we just defined in the code sample above is all that's required to use the form just like any other form. The one issue to be aware of is validation. When using DynaActionForm, there is an assumption that validation is handled someplace other than the ActionForm. It is possible to implement validation within your Action itself, but there is a better approach.

To do validation, you can use the DynaValidatorForm, or DynaValidatorActionForm, which are both found in the org.apache.struts.validator package. By extending the DynaActionForm, basic field validation can be provided, based on an XML file. Validation is based on the key passed into the validator. This key is the name attribute from the struts-config.xml file. This should match the form's elements name attribute in the validation.xml file.

Multiple Application Support

It is possible in Struts 1.1 to have multiple sub-applications defined and supported. What this means is that you can break your application into various sub-applications for better maintenance. You no longer have to camp outside of the person’s cube who has the one and only struts-config.xml file checked out of source control.

Another reason to consider using sub-applications is for control flow that varies by client. In some applications, you may have a standard set of pages, but the control flow may vary depending on what client logs into the application. You could store this control flow metadata into a database and generate the web.xml file (or portions thereof), along with all of the various struts-config.xml files.

If you ever worked with Struts 1.x, you probably noticed that many of the elements defined in the web.xml file have been moved to the struts-config.xml file in Struts 1.1. This is because they are now application-specific. Multiple sub-applications are identified by a prefix at the beginning of the context-relative portion of the request URI. If no application prefix can be matched, the default configuration is selected. The default has a prefix equal to a zero-length string. Implementing the default this way allows for backward compatibility with Struts 1.0.x, where it was possible to only have one application defined.

If you have a large-scale application that contains different functional areas, then it would make sense to consider having sub-applications that work together instead of one big application. The web.xml file below shows how sub-applications can be defined.

<!-- The default sub-application -->
<init-param>
   <param-name>config</param-name>
   <param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>

<!-- The catalog sub-application -->
<init-param>
   <!-- catalog prefix -->
   <param-name>config/catalog</param-name>
   <param-value>/WEB-INF/struts-config-catalog.xml</param-value>
</init-param>

<!-- The sorter sub-application -->
<init-param>
   <!—sorter prefix -->
   <param-name>config/sorter</param-name> 
   <param-value>/WEB-INF/struts-config-sorter.xml</param-value>
</init-param>

When using sub-applications, you might define the context-relative request URIs to specify which sub-app to use. For example, the action on a form might appear as:

<html:form action="/logon" >

which refers to the default sub-application or

<html:form action="/catalog/listCds" >

which refers to the action class in the catalog sub-application. You don’t actually have to do this. You can use /listCds if you want, within the catalog sub-application. The basic rule is this: all struts-config.xml parameters that were context-relative in 1.0 are now sub-app-prefix-relative in 1.1. That way, a single application can be used as either the default sub-application, or as a named sub-application with no change.

Sue Spielman is an associate editor for ONJava.com, covering JSP and Servlets technologies. She is also President and Senior Consulting Engineer for Switchback Software LLC.


Read more JSP and Servlets columns.

Return to ONJava.com.

Copyright © 2007 O'Reilly Media, Inc.