Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Added common problems section and several clarifications

...

Built in Type Conversion Support

Type Conversion is implemented by XWork.

Wiki Markup
{snippet:id=javadoc|javadoc=true|url=com.opensymphony.xwork2.conversion.impl.XWorkBasicConverter}
  • Enumerations
  • BigDecimal and BigInteger

Relationship to Parameter Names

The best way to take advantage of the framework's type conversion is to utilize complete objects. There is no need to capture form values using intermediate Strings and primitives and then convert those values to full objects in an Action method. Instead, the framework can read from and write to properties of objects addressed via OGNL expressions and perform the appropriate type conversion for you.

Here are some tips for leveraging the framework's type conversion capabilities:

  • Use complex OGNL expressions - the framework will automatically take care of creating the actual objects for you.
  • Use JavaBeans! The framework can only create objects if the objects that obey the JavaBean specification and , provide no-arg constructions , as well as and include getters and setters where appropriate.
  • Remember that person.name will call getPerson().setName(), but if in order for . If the framework to create creates the Person object for you, it remember that a setPerson method must also exist.
  • The framework will not instantiate an object if an instance already exists. The PrepareInterceptor or action's constructor can be used to create target objects before type conversion.
  • Wiki Markup
    For lists and maps, use index notation, such as _people\[0\].name_ or _friends\['patrick'\].name_. Often these HTML form elements are being rendered inside a loop. For [JSP Tags], use the iterator tag's status attribute. For [FreeMarker Tags], use the special property $\{foo_index\}\[\].
  • For multiple select boxes, it isn't possible to use index notation to name each individual item. Instead, name your element people.name and the framework will understand that it should create a new Person object for each selected item and set its name accordingly.

...

By default, the conversion interceptor is included in struts-default.xml in the default stack. To keep conversion errors from reporting globally, change the interceptor stack, and add additional validation rules.

Common Problems

Null and Blank Values

Some properties cannot be set to null. Primitives like boolean and int cannot be null. If your action needs to or will accept null or blank values, use the object equivalents Boolean and Integer. Similarly, a blank string "" cannot be set on a primitive. At the time of writing, a blank string also cannot be set on a BigDecimal or BigInteger. Use server-side validation to prevent invalid values from being set on your properties (or handle the conversion errors appropriately).

Interfaces

The framework cannot instantiate an object if it can't determine an appropriate implementation. It recognizes well-known collection interfaces (List, Set, Map, etc) but cannot instantiate MyCustomInterface when all it sees is the interface. In this case, instantiate the target implementation first (eg. in a prepare method) or substitute in an implementation.

Generics and Erasure

The framework will inspect generics to determine the appropriate type for collections and array elements. However, in some cases Erasure can result in base types that cannot be converted (typically Object or Enum).

The following is an example of this problem:

Code Block

public abstract class Measurement<T extends Enum>
   public void setUnits(T enumValue) {...}
}

public class Area extends Measurement<UnitsOfArea> {
  @Override
  public void setUnits(UnitsOfArea enumValue){...}
}

Although to the developer the area.setUnits(enumValue) method only accepts a UnitsOfArea enumeration, due to erasure the signature of this method is actually setUnits(java.lang.Enum). The framework does not know that the parameter is a UnitsOfArea and when it attempts to instantiate the Enum an exception is thrown (java.lang.IllegalArgumentException: java.lang.Enum is not an enum type).

Next: Interceptors