We've been using OpenAMF to connect a Flex client to a Tomcat server in the current project I'm working on. I'm impressed with how well OpenAMF works, but there were a few gotchas we ran across when trying to set up and configure everything. Here are some things to keep in mind if you decide to use OpenAMF in your own projects.
We use the Value Object pattern in order to transfer data between client and server. Rather than call a remote method with different types of parameters, we'll package everything up into a Value Object and send the Value Object over the wire. This is especially handy because with OpenAMF we can map an ActionScript class to a Java class. If we send a PersonVO ( defined in Person.as ) as a method parameter, we can type that parameter as a PersonVO ( defined in Person.java ) on the server.
In order to accomplish this, there are two things you need to do:
- Create a mapping in the WEB-INF/openamf-config.xml file on the server
- Associate the string name to the class instance on the client
For #1, open up the config file and add a mapping like this somewhere in the config file under the config root element:
<custom-class-mapping> <java-class>com.whatever.vo.PersonVO</java-class> <custom-class>com.whatever.vo.PersonVO</custom-class> </custom-class-mapping>
For #2, we need to add an Object.registerClass() call on the client sometime during the application startup process:
Object.registerClass( "com.whatever.vo.PersonVO", com.whatever.vo.PersonVO );
The above is necessary to convert the ValueObjects received from the server into their native ActionScript 2 class equivalents.
The last item I wanted to mention is to be careful with your ValueObjects whenever you have complex types in them. For instance, if a PersonVO has a "books" array (of BookVO instances), it's very important that the books array is never initialized in the VO. That is, this code:
class PersonVO {
public var books:Array; // of BookVO
public function PersonVO() {
books = new Array();
}
}
... will cause problems when you get the data from the server. The constructor is called after all of the values are set, so you'll never get the right data from books because you're always overwriting it! Remember to keep your constructors in your ValueObjects empty or else you might overwrite data accidentally.
The reason we ran into the constructor issue was that we were creating some mock ValueObjects client side because the server code wasn't ready yet. In testing the client, instead of making an actual remote call we'd make a call that used setInterval to construct some VOs and pass them as parameters back, simulating the onResult method of Flash Remoting. Our VO constructors created new complex objects so that we could create our mock data easily. It was only when we switched from the mock calls to the real ones did we run into the issue, and boy was that fun to debug...
I hope this helps someone in the future using OpenAMF on their Flash / Flex projects!
Now, if only ColdFusion could map .cfc's to .as files as easily. I've used the _remoteClass trick in previous projects, but when you have VOs that contain arrays of other VOs that contain more VOs, it gets complex fast. We chose Java over ColdFusion simply because OpenAMF provided a more robust Flash Remoting solution, and made the client-server integration layer easier to write.
