XWork : Type Conversion
This page last changed on Jul 21, 2004 by unkyaku.
Type conversion allows you to easily convert objects from one class to another. Whenever XWork attempts to get or set a property on an Action or object and the Class of the value to be get/set is not what is expected, XWork will try to convert it to the correct class. A common use case is when submitting forms on the web, where we are usually converting to and from String classes. A good example is date conversion. Let's suppose we have the following classs: public class Foo implements Action { private Date date; public void setDate(Date date) { this.date = date ; } public String execute() { // do work here } } XWork's type converter would allow us to pass in the String "07/08/2003" and have it be automatically converted to a Date object that's been set to July 8, 2003. XWork already supports basic type conversion, but you can also use your own type converters. To define a custom type converter, you'll need to perform the following steps:
Defining Conversion RulesConversion rules can be defined at both the class level as well as the application level.Class-specific conversion rulesTo define a class-specific conversion rules, create a file named className-conversion.properties. The syntax for these files are:property = full.class.name.of.converter Collection_property = full.class.name Map_property = full.class.name This file defines the type converter to use for properties of an Action or object. If a property is a Collection (List only) or Map, you can also specify the type of elements in the Collection/Map. Please note that there are some issues to consider when working with type conversion in collections. When looking for a type converter, XWork will search up the class hierarchy and directly implemented for conversion rules. Given the following class hierarchy:interface Animal; class AnimalImpl implements Animal; interface Quadraped extends Animal; class QuadrapedImpl extends AnimalImpl implements Quadraped; XWork will look for a conversion rule in the following files in the following order: QuadrapedImpl-conversion.properties Quadraped-conversion.properties AnimalImpl-conversion.properties Animal-conversion.properties Application-wide conversion rulesTo define application-wide conversion rules, create a file named xwork-conversion.properties and place it in the root classpath. The syntax for this file is: full.class.name = full.class.name.of.converter When looking up a default converter, XWork will search up the class hierarchy to find the appropriate converter. Given the class hierarchy above, XWork will look for a conversion rule for the class in the following order: QuadrapedImpl AnimalImpl An ExampleTo use the Contact example (where Contact is a persistent object), let's say we have the following Action: public class AddContactAction implements Action { private Contact contact1; private Contact contact2; public void setContact1(Contact contact) { this.contact1 = contact; } public void setContact2(Contact contact) { this.contact2 = contact; } public String execute() { … } } What we're expecting from the UI is for contact to be "1", the primary key of the contact. We want the type converter to convert the string "1" to the Contact with a contactId of 1. Likewise, we'd like the converter to be able to reverse the operation. When displayed, a Contact object should print out its contactId as a String. The first step is to create our custom TypeConverter:public class ContactConverter extends ognl.DefaultTypeConverter { public Object convertValue(Map ognlContext, Object value, Class toType) { if( toType == String.class ) { Contact contact = (Contact)value; return new String(contact.getContactId()); } else if( toType == Contact.class ) { Integer id = new Integer((String)value); Session session = … // get a Hibernate Session Contact contact = (Contact)session.load(Contact.class, id); return contact; } return null; } } The next part is to bind our ContactConverter to the previous AddContactAction. I'll bind the ContactConverter to the AddContactAction by creating a file called AddContactAction-conversion.properties that's in the same directory as the AddContactAction class. I would then populate the properties file as follows:contact1 = com.acme.ContactConverter contact2 = com.acme.ContactConverter Now, when XWork attempts to populate your object from parameters, you'll be given the actual instances of Contact from your database. Having said all that, I can't really recommend doing database lookups here as a best practice. In fact, I'd say it's not such a good idea, but it does illustrate type converters well![]() |
![]() |
Document generated by Confluence on Dec 12, 2004 12:35 |