Overview | Package | Class | Tree | Deprecated | Index | Help
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES

## Package org.apache.struts.util

The Utilities package provides a variety of families of classes, to solve problems that are commonly encountered in building web applications.

See:
Description

Class Summary
ArrayStack | Implementation of the `java.util.Stack` API that is based on an `ArrayList` rather than a `Vector`.
BeanUtils | Deprecated. At some point after Struts 1.0 final, will be replaced by an equivalent class in the Jakarta Commons Beanutils package.
ConvertUtils | Deprecated. At some point after Struts 1.0 final, will be replaced by an equivalent class in the Jakarta Commons Beanutils package.
ErrorMessages | Deprecated. Use org.apache.struts.action.ActionErrors instead
FastArrayList | Deprecated. At some point after Struts 1.0 final, will be replaced by an equivalent class in the Jakarta Commons Collections package.
FastHashMap | Deprecated. At some point after Struts 1.0 final, will be replaced by an equivalent class in the Jakarta Commons Collections package.
FastTreeMap | Deprecated. At some point after Struts 1.0 final, will be replaced by an equivalent class in the Jakarta Commons Collections package.
GenericConnection | Generic wrapper implementation of a Connection that works with `GenericDataSource` to wrap connections for any JDBC driver.
GenericDataSource | Generic data source implementation of the `DataSource` interface.
IteratorAdapter | Utility method for converting Enumeration to an Iterator class.
MessageResources | General purpose abstract class that describes an API for retrieving Locale-sensitive messages from underlying resource locations of an unspecified design, and optionally utilizing the `MessageFormat` class to produce internationalized messages with parametric replacement.
MessageResourcesFactory | Factory for `MessageResources` instances.
PropertyMessageResources | Concrete subclass of `MessageResources` that reads message keys and corresponding strings from named property resources in the same manner that `java.util.PropertyResourceBundle` does.
PropertyMessageResourcesFactory | Factory for `PropertyMessageResources` instances.
PropertyUtils | Deprecated. At some point after Struts 1.0 final, will be replaced by an equivalent class in the Jakarta Commons Beanutils package.
RequestUtils | General purpose utility methods related to processing a servlet request in the Struts controller framework.
ResponseUtils | General purpose utility methods related to generating a servlet response in the Struts controller framework.
ServletContextWriter | A PrintWriter implementation that uses the logging facilities of a `javax.servlet.ServletContext` to output its results.

## Package org.apache.struts.util Description

The Utilities package provides a variety of families of classes, to solve problems that are commonly encountered in building web applications.

[Introduction] [Beans and Properties] [Collection Classes] [JDBC Connection Pool] [Message Resources]

### Introduction

The Struts Utilities Package offers several families of classes that assist in solving commonly encountered problems 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 are also suitable for general Java application programming. The following families are included:

- Beans and Properties - A family of utility classes for manipulating JavaBeans, as well as getting and setting properties, without hard coding the names or data types of the property getter and setter methods.
- Collection Classes - A family of specialized classes supporting the Collections API, designed for use in multithread environments where the vast majority of accesses are read only.
- JDBC Connection Pool - A very simple connection pool that can be utilized in web applications or other environments that need to share a limited number of JDBC Connections across a much larger number of active users.
- Message Resources - A family of classes that features access to internationalized message strings based on a message key coupled with a `java.util.Locale` object representing a particular user's preferred language.

### Beans and Properties

FIXME

FIXME some parts of this might me moved to Taglibs

The `BeanUtils` and `PropertyUtils` utilities are used through out struts including the `IteratorTag, WriteTag`. Much of these utilities rely on and make use of Java reflection, to manipulate Java beans . Creating a valid Java bean is essential ! Briefly referring to the example class `ProductBean` below would follow these rules :

- The class must a null constructor, or no constructor
- It's class declaration must be public
- The name for the property say 'value' would have a 'get' method of getValue()
- The 'get' and 'set' methods to be visible must be public.
- If desired the 'is' prefix can be used in place if 'get' for a boolean.
- Other requirements can be found here.

            public class ProductBean() {
               private String value;
               public String getvalue() (return this.value}
               public void setvalue(String value) (this.value = value}
            }

Observing these conventions will avoid unnecessary errors and save time.

This makes it possible to create a JSP page such as:

            <logic:iterate id="product" name="receivedForm" property="receivedList">
                  <bean:write name="product" property="description" />
                  <bean:write name="product" property="value" />
            </logic:iterate>

In this case receiveForm is an ActionForm, with a definition such as

            public class ReceivedForm extends ActionForm  {
             private ProductList productList;
             public void setReceivedList(Enumeration enum) {
                 productList = new ProductList(enum,Limits.ARRAY_SIZE_MIN);
             }
             /**
              * Defined so java.bean reflection will see getReceivedList
              * as a getter for receivedList
              */
             public void setReceivedList(ProductList productlist) {

             }

             /**
              * Returns an Array list of ProductBeans.
              */
             public ProductList getReceivedList() {
               return productList;
             };
           } //ReceiveForm

### Collection Classes

##### Background

Version 1.2 of the Java 2 Standard Edition (J2SE) introduced a powerful set of collection classes that are generally useful in Java programming, based on the fundamental interfaces `java.util.Collection`, `java.util.List`, `java.util.Map`, and `java.util.Set`. Compared to the collection classes available in JDK 1.1 (principally `java.util.Hashtable` and `java.util.Vector`), the new classes offer much richer functionality as well as the opportunity to improve performance.

The performance increase potential comes from the fact that none of the methods used to access the new collection classes are `synchronized` as were the methods of `Hashtable` and `Vector`. In a single thread application, this means that method calls can execute much more quickly because synchronization is never necessary. In a multiple thread environment, though, it is up to the developer to ensure that any method calls made while another thread is modifying the collection must be synchronized.

There are many cases in multithreaded server environments (such as a web application) where data structures are initialized at application startup time, and are then predominantly accessed in a read-only manner. An example of this is the Struts controller application, which initializes its collection of `ActionMapping` instances (each corresponding to an `<action>` element in the `struts-config.xml` file) at startup time. However, it is legal for an application to dynamically change the set of available mappings while the application is running -- so, to be safe, it would normally be necessary to synchronize access to such collections, even though 99% of those accesses are read only and would not otherwise require synchronization.

To deal with such scenarios, the Struts utility package includes a series of specialized collection classes designed to operate in a multithread environment where the large majority of accesses are read only, without requiring synchronization on every operation, but still protecting against the possibility of runtime modifications to the underlying collection.

##### Theory of Operation

Each of the available collection classes operates in one of two modes: fast or slow. When first created, the collection operates in slow mode, which is appropriate for initially populating the contents of the collection. Once the initial population is complete, switch to fast mode by calling `setFast(true)` for maximum performance when most accesses are read-only.

When operating in slow mode, all methods that access this collection, even read-only methods, are synchronized - resulting in impacts on performance similar to that always performed by the `Hashtable` and `Vector` classes. This mode is appropriate when you are initializing the content of the collection, or when you need to perform a large series of updates.

Using fast mode, on the other hand, causes method calls to operate in the following manner:

- Method calls that access information from the collection, but do not modify it, are executed without synchronization.
- Method calls that modify the structure of a collection do so by synchronizing, cloning the existing collection instance, modifying the cloned instance, and then replacing the current collection instance.

As you can see, modification operations are much more expensive when operating in fast mode, but doing things in this way allows read only operations, which should be the vast majority, to operate at maximum speed.

If your collection will never be accessed in a multithread environment, you should use one of the standard collection classes instead, without synchronization, for maximum performance.

##### Available Collection Classes

The following collection classes, with the ability to operate in either fast or slow mode, are included:

- org.apache.struts.util.FastArrayList - Similar in functionality to `java.util.ArrayList`.
- org.apache.struts.util.FastHashMap - Similar in functionality to `java.util.HashMap`.
- org.apache.struts.util.FastTreeMap - Similar in functionality to `java.util.TreeMap`.

### JDBC Connection Pool

##### Background

A large number of web applications require interaction with a relational database to access or update persistently stored information. In a typical client-server application, each concurrent user opens their own database connection at program initialization, and uses this connection throughout the period of time the application is open.

While this approach can work well in an environment where the number of active users is reasonably fixed, it does not scale well to a web application where the number of simultaneous users could be very large. In addition, open database connections (even when not actively used) do impose some overhead costs, and most web application users (at a given instant) are reviewing the contents of a previously generated page (or typing in their next set of input information), rather than actively accessing the database.

To deal with this situation, several basic strategies are possible:

1. Open a connection on each request, do whatever processing is required, and then close the connection.
2. Open a connection for each user, and store it in the user's session.
3. Share a "pool" of open connections between all of the application's current users.

The first strategy has the virtue of simplicity - you merely need to open a database connection any time you need one, perform the appropriate data accesses and updates, and close the connection. However, it suffers from a major disadvantage: on most databases, establishing a connection can be very time consuming (often requiring multiple seconds of clock time), in order to perform a database transaction that might take milliseconds.

Opening a connection per user, as the second strategy suggests, is similar to the approach taken with client-server applications described earlier. As long as the number of simultaneous users can be controlled at a manageable number (such as with many intranet-based applications), this approach is feasible. However, it becomes unmanageable when the number of users can climb rapidly to very large numbers (as is typical of many Internet-hosted public applications), and still requires more overhead than a strategy that would share a smaller number of connections.

Connection pooling is an implementation of the third strategy. It is based on the assumption that most users of a web application will be interacting locally with the last page that was sent to their browser. The number of users actually performing a request at any given time is usually a very small percentage of the total number of active users, and during request processing is the only time that a database connection is required.

Struts provides a simple connection pool class called `org.apache.struts.util.GenericDataSource`. It allows you to configure a set of connections (with identical connection parameters) to a particular database, using a particular JDBC driver, and then share those connections among a number of simultaneously operating threads (such as the various request threads that are concurrently active in a servlet container). The `GenericDataSource` class implements the `javax.sql.DataSource` interface from the Java Database Connectivity (version 2.0) Standard Extension API, so any programs you use to access it should reference this interface, rather than the class name directly. That way, you can migrate to a more advanced connection pool implementation later, with little or no impact on your application.

For more information about the JDBC 2.0 Standard Extension API, you can download the spec (and the corresponding API classes), from http://java.sun.com/products/jdbc. You can also find pointers to a substantial amount of other information about available JDBC drivers, programming tutorials, and so on, at this web address.

##### Initializing and Finalizing the Connection Pool

The following instructions show you how to configure the connection pool class and use it, from any Java application. As you will see below, the Struts controller servlet offers you convenient mechanisms to configure one or more connection pools, and make them available to Action classes and JSP pages by storing the connection pool instances as servlet context attributes (in JSP terms, application-scope beans).

To configure a `GenericDataSource` instance, you must first create one:

        GenericDataSource dataSource =
          new GenericDataSource();

Next, you must set the appropriate properties, by calling the corresponding JavaBeans property setter methods provided by this class. (See the Javadoc API for the GenericDataSource class for more details on the available properties). An example of configuring the connection pool object to a Postgres database might look like this:

        dataSource.setAutoCommit(false);
        dataSource.setDescription("My Database Connection Pool");
        dataSource.setDriverClass("org.postgresql.Driver");
        dataSource.setMaxCount(4);
        dataSource.setMinCount(1);
        dataSource.setPassword("mypassword");
        dataSource.setUrl("jdbc:postgresql://localhost/mydatabase");
        dataSource.setUser("myusername");

Finally, you must `open()` the connection pool. This will establish the initial connections to the database (based on the value you have configured for the `minCount` property). As you use connections from the pool in multiple threads, additional connections (up to the number you specify with the `maxCount` property) will be created as needed.

        try {
            dataSource.open();
        } catch (SQLException e) {
            ... deal with exception ...
        }

When you are completely through with the connection pool, you can gracefully close all of the currently open database connections by executing

        try {
            dataSource.close();
        } catch (SQLException e) {
            ... deal with exception ...
        }

##### Using the Generic Connection Pool

To access the database from within an application class, you must follow a simple four-step procedure each time you need a connection:

1. Acquire a connection from the connection pool.
2. Perform the database operations required by your application.
3. Cause the last database transaction to be committed or rolled back (commits are required on many databases to ensure that the database operations you just performed are permanently stored or not).
4. "Close" the connection, which returns it to the connection pool for reuse later.

An example code sequence that performs this procedure might look like this:

        DataSource dataSource = ... acquire reference to dataSource ...
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        try {
            conn = dataSource.getConnection();
            stmt = conn.prepareStatement("SELECT cust_id, name FROM customers" +
              " WHERE (last_purchase_date >= ?)" +
              " ORDER BY name");
            stmt.setDate(1, lastPurchaseDate);
            rs = stmt.executeQuery();
            while ((row = rs.next()) != null) {
                ... process this row ...
            }
            rs.close();
            rs = null;
            stmt.close();
            stmt = null;
            conn.commit();
            conn.close();
            conn = null;
        } catch (SQLException e) {
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException f) {
                    ;
                }
                rs = null;
            }
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException f) {
                    ;
                }
                stmt = null;
            }
            if (conn != null) {
                try {
                    conn.rollback();
                } catch (SQLException f) {
                    ... deal with exception ...
                }
            }
            ... deal with exception ...
        } finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException f) {
                    ... deal with exception ...
                }
                conn = null;
            }
        }

One aspect of the above code example that might surprise developers who have previously used JDBC connections individually is the idea of calling close() on the Connection. Normally, this call will sever the Connection's underlying link to the database, and render that Connection unuseable for any further operations. However, when used in a connection pool environment, the actual Connection you receive by calling `getConnection()` is a customized "wrapper" around a real JDBC Connection instance. Calling `close()` on this wrapper simply causes this connection to be returned to the pool.

What would happen if your application failed to return a connection to the pool when it was through? As you might expect, that particular connection becomes "lost" to the server, and can never again be used (even though it remains connected to the database throughout the life of the connection pool itself). If this happens repeatedly, you will eventually exhaust the pool of available connections, and application processing will stop.

To avoid this problem, your application logic must ensure that it ALWAYS returns allocated connections to the pool, no matter what problems might happen in the interim. The Java language provides one convenient mechanism to achieve this - using a `finally` block, as in the code example above. This is not the only way to ensure that a connection is always returned, but it is very convenient.

##### Using Connection Pools with the Struts Controller Servlet

If your application is running underneath the Struts controller servlet (`org.apache.struts.action.ActionServlet`), you can take advantage of the servlet's ability to preconfigure one or more connection pools for you, based on information included in the `struts-config.xml` file. Simply include a section that looks like this:

        <data-sources>
          <data-source>
            <set-property property="autoCommit"
                          value="false"/>
            <set-property property="description"
                          value="Example Data Source Configuration"/>
            <set-property property="driverClass"
                          value="org.postgresql.Driver"/>
            <set-property property="maxCount"
                          value="4"/>
            <set-property property="minCount"
                          value="2"/>
            <set-property property="password"
                          value="mypassword"/>
            <set-property property="url"
                          value="jdbc:postgresql://localhost/mydatabase"/>
            <set-property property="user"
                          value="myusername"/>
          </data-source>
        </data-sources>

After being initialized, the connection pools will be stored as servlet context attributes under the bean name specified by the `key` attribute. If you did not specify a `key`, the default key is the value of the string constant `Action.DATA_SOURCE_KEY`. Thus, you can access and utilize a connection, from within an `Action` class, like this (for the default data source):

        DataSource dataSource = (DataSource)
          servlet.getServletContext().getAttribute(Action.DATA_SOURCE_KEY);
        conn = dataSource.getConnection();
        ... perform required functions as in the previous example ...
        conn.close();

### Message Resources

##### Background

Modern applications often include the requirement to support multiple languages, for users who prefer to interact in a language other than the default language configured on the server platform. In addition, sentences often need to be constructed, with dynamic content whose placement in the message depends on the standard sentence structure in that particular language.

The standard Java platform includes a family of classes (`java.util.ResourceBundle`) designed to support looking up message strings based on a standard "key". The resource bundle classes automatically access a Java class (or properties file) that is named with a naming convention that includes the Locale to which messages in that class (or file) pertain. However, this selection is based only on the default Locale of the server platform, and cannot be adjusted on a per-user basis as required for an internationalized web application.

Struts includes a family of classes (`org.apache.struts.util.MessageResources`) that extends the basic approach to looking up message strings by key, allowing you to optionally specify a Locale along with the key. In this way, you can build applications that let your users select which Locale they wish to operate within, and then look up messages in that language - using the same message keys no matter what language is selected.

In addition to supporting dynamic selection of a Locale for message lookup, the `MessageResources` family of classes optionally allow you to specify up to four parameter replacement objects, which are used to replace the parameter placeholders "{0}" through "{3}" in the retrieved message. This replacement uses the facilities of the standard Java `java.text.MessageFormat` class, which supports many extended formatting capabilities as well.

For more information about internationalized messages, consult the following resources in your Java Development Kit documentation bundle:

- Internationalization Info - General information on Java's standard support for internationalized applications can be found at `<$JAVA_HOME/docs/guide/internat/index.html>`. The "Internationalization Overview" section includes useful information about Locales, localized resources, message formatting, and other relevant topics.
- Internationalization Tutorial - The Java Language Tutorial has a comprehensive trail covering internationalization, available at: http://java.sun.com/docs/books/tutorial/i18n/index.html.
- Javadoc APIs - You will want to consult the Javadoc API documentation for the following standard Java classes:
  - `java.text.MessageFormat`
  - `java.util.ResourceBundle`
  - `java.util.PropertyResourceBundle`
  - `java.util.Properties` - See the documentation for the `load()` method for the valid syntax of properties files that you prepare.

##### Using the Standard MessageResources Implementation

The standard `MessageResources` implementation provided by the Struts library uses Java properties files to initialize message strings, in a manner very similar to that supported by the `java.util.PropertyResourceBundle` class. The following steps are required to use these facilities in your Java application.

First, prepare a Java properties file for each language (or Locale) in which you wish to support your messages. The filenames you use must conform to the naming convention for property resource bundles, as described in the documentation referenced above. Be sure you use the same message keys in each file to identify the same message.

For example, you might prepare files in French, Spanish, and English that contain language-specific versions of the word "Hello". The French file would be named `Messages_fr.properties` and contain the following:

        hi=Bonjour

while the Spanish and English files would be named `Messages_es.properties` and `Messages_en.properties` respectively. The corresponding message string definitions would say `hi=Hola` and `hi=Hello` in these files.

Second, place these properties files into the class path for your application, exactly as you would with class files themselves. The name actually used to load resources will look like a fully qualified Java class name (with appropriate package prefixes), so the file should be nested inside a directory structure that matches the packaging (either in an unpacked directory, or within a JAR file, as appropriate). For example, assume you place directory "foo" on your classpath, and stored the above properties files in directory "foo/com/mycompany/mypackage". (If you were using a JAR file like "foo.jar" instead, the files would be in directory "com/mycompany/mypackage" within the JAR file).

Third, initialize a `MessageResources` object that corresponds to the set of properties files for a particular name, within a particular package. The easiest way to do this is to initialize a variable in your main application class, like this:

        public static MessageResources messages =
         MessageResources.getMessageResources("com.mycompany.mypackage.Messages");

Note that the "com.mycompany.mypackage" part of the name matches the package directory into which you placed your properties files, and "Messages" is the filename prefix for the particular family of properties files supported by this `MessageResources` instance. Depending on your development process, you might find it convenient to store all message strings for an entire application in a single properties file family, or to have several families - in Struts, for example, there is a family of properties files for each Java package.

To access a message string with a particular Locale, execute a statement like this:

        Locale locale = ... select the locale to be used ...
        String message = messages.getMessage(locale, "hi");

In this case, the variable `message` will contain the message string corresponding to the key "hi", in the language that corresponds to the locale that was selected.

For an example of message formatting with replaceable parameters, assume that the message strings looked like this, instead (only the English version is shown - corresponding changes would be made in the other files):

        hi=Hello {0}

Now, you can personalize the retrieved message like this:

        Locale locale = ... select the locale to be used ...
        String name = "Joe";
        String message = messages.getMessage(locale, "hi", name);

and the marker "{0}" will have been replaced by the specified name (Joe), no matter which language is in use. See the JavaDoc API documentation for the `java.text.MessageFormat` class for more advanced uses of the parameter replacement mechanism.

##### Developing Your Own MessageResources Implementation

In the above example, we were using the default `MessageResources` implementation supplied by Struts, which uses property files to store the message strings. It is also possible to create customized mechanisms to retrieve messages (such as loading them on demand from a database). The steps required are as follows:

- Create a customized subclass of `org.apache.struts.util.MessageResources` that implements message lookup operations as you require.
- Create a customized subclass of `org.apache.struts.util.MessageResourcesFactory` that will create an instance of your custom `MessageResources` class when the `createResources` method is called. Note that the "config" argument to this method can be used to select families of messages in any manner appropriate to your needs - you are not required to emulate the "fully qualified Java class name" approach that is used by the standard `PropertyMessageResourcesFactory` class.
- Tell the `MessageResourcesFactory` class the name of the customized `MessageResourcesFactory` implementation to use when creating new factory instances.
- Create a new factory instance.
- Ask the new factory instance to create a `MessageResources` instance for you.

A code example that illustrates this technique is:

        MessageResourcesFactory.setFactoryClass("com.mycompany.mypkg.MyFactory");
        MessageResourcesFactory factory = MessageResourcesFactory.createFactory();
        MessageResources resources =
         factory.createResources("configuration information");

Once you have created your custom MessageResources instance, you utilize it to access message strings (with or without parameter replacement objects), exactly as we illustrated with the standard implementation in the previous section.

##### Using MessageResources With Struts

If your application uses the Struts controller servlet, you can optionally configure Struts to load an application-specific message resources instance for you, and make it available as a servlet context attribute (in JSP terms, an application-scope bean). This mechanism is managed by setting the following servlet initialization parameters in the web application deployment descriptor:

- application - The configuration string that will be passed to the `createResources()` method of the message resources factory, in order to identify the family of resources to be supported. If you use the standard message resources factory, this must be the base fully qualified name of the property resources files used to contain these messages, as illustrated above.
- factory - Fully qualified Java class name of the `MessageResourcesFactory` to be used. By default, the standard implementation provided by Struts (`org.apache.struts.util.PropertyMessageResourcesFactory`) will be used.

Struts provides several JSP custom tags that assume the existence of a `java.util.Locale` attribute in the user's session, under the key named by the constant string value of `Action.LOCALE_KEY`. Your own application logic can set this attribute at any time, or you can ask Struts to set it automatically (if not already set) based on the `Accept-Language` HTTP header included with the request. There are two mechanisms by which you request Struts to perform this service:

- To have this service performed on every request submitted to the controller servlet, set the servlet initialization parameter `locale` to the value `true` in the application deployment descriptor.
- To have this service performed by a JSP page when it is accessed directly by a user, utilize a `<form:html ... locale="true" ... />` tag at the top of each page.

Overview | Package | Class | Tree | Deprecated | Index | Help
PREV PACKAGE NEXT PACKAGE | FRAMES NO FRAMES

Copyright © 2000-2001 - Apache Software Foundation