Pages

Saturday, June 19, 2010

Flex BlazeDS - Java null deserialization problem

Problem:
Default BlazeDS implementation deserializates Action Script NaN to 0 in Java:

Action Script type Number with value: NaN will be deserialized to java.lang.Double with default value 0. In my case it cause problems with persisting such object with Hibernate.
More natural deserialization is NaN to null rather than NaN to 0. Similarly other way: null java.lang.Object to Action Script NaN, not 0 value.

Solution:
Override BlazeDS serialization process with extending BeanProxy class i.e.:
import java.math.BigDecimal;
import java.math.BigInteger;

import flex.messaging.io.BeanProxy;

public class FlexNumberProxy extends BeanProxy {
   
    public Object getValue(Object instance, String propertyName) {
        Class propertyType = getBeanProperty(instance, propertyName).getType();
        Object result = super.getValue(instance, propertyName);
        if (result == null
                && (BigDecimal.class == propertyType
                || BigInteger.class == propertyType
                || Integer.class == propertyType
                || Long.class == propertyType
                || Double.class == propertyType
        )
                ) {
            return new Double(Double.NaN);
        }
        return result;
    }

    public void setValue(Object object, String propName, Object value) {
        if (value!= null && value.getClass().equals(Double.class) && Double.isNaN(((Double) value).doubleValue())) {
            super.setValue(object, propName, null);
        } else {
            super.setValue(object, propName, value);
        }

    }

}
and register these new writed proxy bean somewhere where application initializes with:

PropertyProxyRegistry.getRegistry().register(java.lang.Object.class, new FlexNumberProxy());

2 comments:

  1. Hello Lukasz,

    I would like to ask how I could register it via PropertyProxyRegistry given that I'm using a Spring configuration for my beans.

    If this is not possible, where can I put the PropertyProxyRegistry in my code where it can be seen by my application (somewhere is quite vague IMHO).

    Thanks!

    ReplyDelete
  2. The simplest way to register FlexNumberProxy with PropertyProxyRegistry is using ServletContextListener and its contextInitialized method (method invoked when a web application is deployed).

    If you use spring, you can register it i.e. in any spring's init-method.

    Cheers,
    Lukasz

    ReplyDelete