Skip navigation
Currently Being Moderated

AMF3 serialization problems. How to set a custom BeanProxy?

Dec 7, 2009 9:09 AM

Hi,

 

When I serialize to AMF3 a BigDecimal which it's value is null, on the client Flex app side I recieve 0 instead of null or NaN.

What I would like is that when a java variable pointed to null is serialized, on the client Flex app I recieve null or NaN(if it's a Number on the client side).

Also when I serialize NaN from flex client I would like it to be deserialized to null on the Java side.

 

Is there any way to customize that specific object serialization?

I have read in some places that mentioned the use of a custom bean proxy. But I couldn't find how to implement or configure such a thing.

I'm using BalzeDS AMF3 serialization classes.

 

thanks in advance,

 

Polaco.

 
Replies
  • Currently Being Moderated
    Feb 4, 2010 7:19 AM   in reply to P.o.l.a.c.o

    Hi,

     

    You can find more info in that bug : https://bugs.adobe.com/jira/browse/BLZ-305


    Basically, making a custom BeanProxy consist of making a subclass of BeanProxy.

    To then use it, you need at he initialization of your application to do something like this :

     

    PropertyProxyRegistry.getRegistry().register(rootClass, new MyBeanProxy());

     

    rootClass being the class, comon superclass or interface of the object for which the BeanProxy has been implemented.

     

    Hope this help,

    Nicolas.

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 7, 2010 2:51 AM   in reply to P.o.l.a.c.o

    Hi Polaco,

     

    First,for the BeanProxy, registering against Object class isn't really a great idea and can have some side effects, as I found out recently. If it's possible it's better to use a marker interface, an empty interface that the object you want to serialize with the customization will implement and register the BeanProxy against that interface.

     

    For the marshaller, I found the idea in the BlazeDS dev guide, here http://forums.adobe.com/thread/535610?tstart=0 .

    In the channel definition inside the services-config.xml file, you can specify a <serialization> tag with several options including type-marshaller.

    That's where you have to configure to use your own implementation of the TypeMarshaller interface.

     

    The class implementing it in BlazeDS is ASTranslator, and I think there is also a subclass specific for Java 1.5, can't find the name right now, but I know it's there. So the easiest way to make your own is to have a look at this class, subclass it and adapt with what you wanna do.


    Hope this help,

    Nicolas.

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 7, 2010 1:34 PM   in reply to P.o.l.a.c.o

    Hi Polaco,

     

    I'm not sure adding and repackaging those classes is really authorized. Adding the jar to your project and making sub-classes is probably a better way of doing it.

     

    Anyway, you will face an issue : when you want to send null from java to flex, AmfOutput is already too late to make a conversion to NaN.

    The reason is that hte only thing you have is null, not the actual type of the variable. So you have no way to change it to NaN when it is number related.

     

    That's why I had to use the BeanProxy, at that point, you can find out the type of each properties of a bean, so you can convert to NaN when the type is BigDecimal or other Number kind and the value is null.

     

    Well at least that's the conclusion I've reached so far.

     

    For the typeMarshaller, t's used somewhere in the input process, but I can't find out where tonight, I'll have a look tomorrow.

     

    Regards,

    Nicolas.

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 8, 2010 12:40 AM   in reply to P.o.l.a.c.o

    Hi Polaco,

     

    Normally you can access the protected method from subclasses even in another package.

     

    The type marshaller has the advantage of dealing not only withbeans but also with parameters you pass to a method call. I guess in your case it doesn't really matter.

     

    Regarding the registration against the Object class, the issue is in the way BlazeDS works. BlazeDS is making messages, and those messages are of course subclasses of Object. And those messages including Ack are serialized the same way your objects are. That's where the side-effect can and, more than likely, will occurs.

    The problem is that you're not only customizing your own objetcs but also the one used by BlazeDS.

     

    The best way to understand how all of this works is to launch your sever in debug mode, put breakpoints and launch something.

     

    Here is how I understood it is working :

    When BlazeDS serialize or deserialize something, if it's not a simple type, he will look for a BeanProxy registered to the class of the object. First against the actual class, then against the implemented interfaces, then it goes up in the class hierachy. If it doesn't find any, it will create one based on the default BeanProxy.

    Then, it will use this BeanProxy to have the list of properties of the class, and will getValue or setVlaue when he's reading or writting something on an object.

    There is also a method that handle the creation of the actual object.

     

    If I understand well the idea behind that, the goal is to have blazeDs use the proxy instead of the actual objects and classes so it can uses caches instead of actually using reflexion all the time.

     

    This article is about implementing a beanProxy to add some anotation features to BlazeDS http://www.flexpasta.com/index.php/2008/05/19/blazeds-with-annotations -for-remote-objects/

     

    And this one is using this mechanism to propose a way of handling enum serialization http://flexblog.faratasystems.com/2007/09/16/adding-enum-support-to-fl ex-amf-protocol

     

    Hope this help,

    Nicolas.

     
    |
    Mark as:
  • Currently Being Moderated
    Feb 9, 2010 12:06 AM   in reply to P.o.l.a.c.o

    Hi Polaco,

     

    In BlazeDS the typeMarshaller is set directly on the EndPoint, the code is in the AbstractEndpoint class, so I think this part doesn't apply to your case.

    It's also used in the BeanProxy class in the setValue method where it's retreived from TypeMarshallingContext. I don't know where it's set there in blazeDS, but there is a static method setTypeMarshaller there.

    The other place where it's used in BlazeDS and that make the TypeMarsaller more interesting that the BeanProxy in my case is the MethodMatcher class, where the convertParams method also use the typeMarshaller coming from the TypeMarshallingContext.

     

    I didn't tried serializing without BlazeDS yet, so I can't really make alot of comment, but if you don't use BlazeDS, you shouldn't have the message issue.

     

    For AMF3Input and Ouput, yes you could, as long as you can find a way to decide if a null from Java need to be sent as is or converted to NaN.

     

    Regards,

    Nicolas.

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points