How do I get a strongly typed collection from BlazeDS?
Asked Answered
T

4

6

I've exposed a Spring bean to my Flex app via BlazeDS. In my Java code I return strongly typed lists. e.g.

public List<Folder> getFolders(String path) {
    return dao.getFolders(path);
}

The Flex app receives the data as an ArrayCollection of AS3 Object instances - i.e. not as a ArrayCollection of Folders which is what I want. I've annotated my Flex class as follows:

package myproject.vo {
    import com.adobe.cairngorm.vo.IValueObject;
    import mx.collections.ArrayCollection;

    [Bindable]
    [RemoteClass(alias="myproject.vo.Folder")]
    public class Folder extends PersistentObject implements IValueObject {
        public function Folder() {}
    }
}

I checked that I had getters/setters on my Java Folder class to match the properties in my Flex Folder class. Any ideas?

Tessy answered 18/11, 2009 at 15:25 Comment(1)
I've formatted your code so that the generics don't get treated as HTML.Thence
T
11

I finally resolved this issue following a bit of Googling. Here are the rules of Flex remoting that I found:

  1. Annotate the Flex value object to indicate the Java class that it relates to. This is essential if the package name differs. – e.g. [Bindable][RemoteClass(alias=”package.JavaClass”)] public class FlexClass {}

  2. The constructors MUST match in Flex and Java value objects. I ended up sticking to public no-args constructors just to keep it simple.

  3. Getters and setters MUST match between Flex and Java value objects.

  4. The last rule is a cracker – You MUST instantiate any classes that you need to deserialize to. On the face of it this shouldn’t be a problem however I spent days trying to deserialize the results of a remote getObjectsAtPath() call - a list of PersistentObjects which contained instances of Folder and Document (both are subclasses of PersistentObject). If you don’t explicitly instantiate the class (in my case the Folder class) it does NOT get included in the SWF file (unlike Java)! I eventually create a dummy variable of type Folder to get around this.

Thanks to everyone for your suggestions.

Tessy answered 19/11, 2009 at 16:21 Comment(5)
Can't emphasize #4 enough. If you want to pass an ArrayCollection of Foo's from Flex->Java, you must do something along the lines of arrayCollection.addItem(obj as Foo);Nonlegal
In regards to #4, you can trick the compiler into thinking you are instantiating the dummy objects by placing them in a "if (0) {...}" block. Don't try "if (false) {...}", it seems the compiler is clever enough to figure out that the code never gets executed.Lilliamlillian
You sir, are correct. I can't begin to guess how many hours you saved me. Can you share the link for where you found number 4?Pending
Now I have to go think about what comment I'm going to put next to my unused code "var foo:Thing = new Thing()". :)Pending
Holy crackers Batman -- your #4 just saved me many hours of lost time! I would also add to your list that if you don't have a public getter & setter in Java, the property won't be marshaled/unmarshaled. A getter by iteslf (e.g. readonly property) won't work.Hawaii
N
0

I'm looking at all of my server-side code, and I can't remember if this was necessary or not, but on the Java side, I declare the return values as strongly-typed Lists:

public List<Folder> getFolders(String path) { 
    return dao.getFolders(path); 
}
Nikolos answered 18/11, 2009 at 18:7 Comment(4)
me too - looks like my angled brackets were stripped out.Tessy
The angle brackets, aka Generics, are stripped at compile time.Thence
I meant stripped out by the StackOverflow text editor. Either that or I omitted then when typing up the question. I always use generics to strongly type lists in Java.Tessy
Ah, ok. I had put them back in for you. Check out the details on the Stack Overflow formatting rules and buttons. There are some coder-friendly things in their to format your code in a presentable way.Thence
T
0

Java generics are stripped out at compile time. The JVM does not type collections at run time. Anyway, I don't see your calling code, but it should be putting the returned value from java into a variable that is declared kinda like this:

folders:ArrayCollection.<String>
Thence answered 19/11, 2009 at 8:12 Comment(0)
F
0

You mentionned that your Folder class is complex ; does it mean that it contains references to other objects ? In this case don't you have to map every other classes (and check the setters / getters, especially for boolean) ?

Feuillant answered 19/11, 2009 at 9:9 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.