Use PropertyUtils.getSimpleProperty()
to access a bean property by name; this method takes the name of a property and returns
the value of that property. The following example uses this method to
retrieve the name
property from a
Person
bean:
import org.apache.commons.beanutils.PropertyUtils; Person person = new Person( ); person.setName( "Alex" ); String name = (String) PropertyUtils.getSimpleProperty( person, "name" ); System.out.println( name );
PropertyUtils.getSimpleProperty(
)
invokes the public method getName(
)
on an instance of Person
, returning the value of the name
property. The previous example executes
and prints out the name "Alex."
A simple bean property is a private member variable that can be
accessed with a getter method. If a property can be read via a getter
method, that getter method is said to be the read method
for the
named property. If the property can be modified with a setter method,
that setter method is said to be the write
method
for the named property. The Person
bean in Example 3-4 defines two simple bean
properties, name
and favoriteColor
.
Example 3-4. A Person bean with two simple properties
package com.discursive.jccook.bean; public class Person { private String name; private String favoriteColor; public Person( ) {} public String getName( ) { return name; } public void setName(String name) { this.name = name; } public String getFavoriteColor( ) { return favoriteColor; } public void setFavoriteColor(String favoriteColor) { this.favoriteColor = favoriteColor; } }
The class defined in Example 3-4
is used in the following sample code, which creates a Person
object, sets the name
and favoriteColor
properties, and demonstrates the
use of Property.getSimpleProperty( )
to retrieve both properties by name:
import org.apache.commons.beanutils.PropertyUtils; // Create a person Person person = new Person( ); person.setName( "Alex Wolfe" ); person.setFavoriteColor( "Green" ); try { String name = (String) PropertyUtils.getSimpleProperty( person, "name" ); String favoriteColor = (String) PropertyUtils.getSimpleProperty( person, "favoriteColor" ); System.out.println( "The Person: " + name + " likes " + favoriteColor ); } catch (IllegalAccessException e) { System.out.println( "You are not allowed to access a property!" ); } catch (InvocationTargetException e) { System.out.println( "There was a problem invoking the method." ); } catch (NoSuchMethodException e) { System.out.println( "There is no method to get a property." ); }
Take note of the extensive exception handling required to retrieve
two bean properties; three separate exceptions can be thrown by getSimpleProperty( )
. The first, IllegalAccessException
, is thrown if the
getter method is not accessible (not public). InvocationTargetException
is thrown if the
getter method throws an exception, and NoSuchMethodException
is thrown if you specify
a bean property that does not exist on an object; for example,
attempting to retrieve the numberOfDoors
property from the person
object above would throw a NoSuchMethodException
because there is no
getNumberOfDoors( )
method.
To simplify the examples in this chapter, most examples will
omit the try
/catch
or catch the general Exception
—to do otherwise would be a
needless waste of paper. As a general programming practice, catching
the general Exception
should be
avoided; well-written code usually catches individual, specific
exceptions. But, in this case, catching the general Exception
may save you a great deal of
hassle.
Using PropertyUtils.getSimpleProperty(
)
when you could simply call a get method might seem like an
unwieldy solution to a very simple problem, but the alternative—calling
a getter method—locks you into a specific bean property at compile time.
This may be unacceptable if you are designing something generic like a
templating system or an expression language interpreter; you may need to
access an arbitrary property of an arbitrary object known only at
runtime. The ability to retrieve the value of a bean property by name
lies at the heart of a number of important tools, such as Struts, Apache
Velocity, Commons JEXL, and utilities from Commons Collections.
Accessing bean properties by name is an appropriate solution for a
system that needs a high level of flexibility.
The next three recipes focus on accessing different types of bean
properties: nested, indexed, and mapped. Simple properties may also be
retrieved with PropertyUtils.getProperty(
)
; this method is described in Recipe 3.8.
This recipe mentions Apache Struts, a web application MVC framework. For more information about the Struts project, see http://struts.apache.org/. Apache Velocity and Commons JEXL are discussed in Chapter 9, and Commons Collections is discussed in Chapter 5.