java flex actionscript-3 blazeds jodatime

Marshalling personalizado de Java a Flex a través de BlazeDS



actionscript-3 jodatime (3)

Mi equipo está armando una aplicación Flex de prueba de concepto instalada sobre un servidor basado en Spring utilizando BlazeDS.

Hacemos una gran cantidad de cálculos de fechas, por lo que usamos Joda Time extensamente en todo el código y en nuestro modelo de dominio.

Ahora estamos tratando de descubrir cómo podemos seguir usando Joda Time en nuestros DTOs que se envían de ida y vuelta con la interfaz Flex a través de BlazeDS.

Nuestro objetivo es utilizar el tipo de datos Actionscript 3 Date en el lado Flex y tener ese mapa para nuestro uso de los tipos LocalTime LocalDate , LocalDate y LocalTime LocalDate de Joda time en el lado Java.

Podemos resolver el problema de convertir el tipo de Date Actionscript 3 al llamar a Java con un contador de referencias personalizadas conectado a BlazeDS, pero parece que solo se invoca para la dirección Flex-> Java / BlazeDS y no para la dirección Java / BlazeDS-> Flex. .

Ahora estoy buscando implementaciones personalizadas de PropertyProxy para BlazeDS, pero tampoco parece lo correcto.

La otra idea era implementar Externalizable en nuestros Java DTOs, pero parece demasiado trabajo, especialmente cuando miro al rival GraniteDS de BlazeDS y eso muestra cómo conectar el soporte de Joda Time en su documentación con un convertidor de tipos simple.

Cualquier idea apreciada.



OK - He encontrado la respuesta por mi cuenta. Esto implicó escribir mi propia clase de punto final AMF + clases de serialización relacionadas. Debo decir que los chicos de http://flexblog.faratasystems.com han sido una gran fuente de inspiración para hackear BlazeDS.

Este código realmente debería ser incorporado en BlazeDS mismo o en algún proyecto de extensión de código abierto, es muy básico.

Definición del canal

<channel-definition id="my-amf" class="mx.messaging.channels.AMFChannel"> <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf" class="ch.hedgesphere.core.blazeds.endpoint.AMFEndpoint"/> <properties> <serialization> <type-marshaller>ch.hedgesphere.core.blazeds.translator.HedgesphereASTranslator</type-marshaller> </serialization> </properties> </channel-definition>

Punto final AMF personalizado

package ch.hedgesphere.core.blazeds.endpoint; import ch.hedgesphere.core.blazeds.serialization.Serializer; public class AMFEndpoint extends flex.messaging.endpoints.AMFEndpoint { @Override protected String getSerializerClassName() { return Serializer.class.getName(); } }

Serializador personalizado

package ch.hedgesphere.core.blazeds.serialization; import java.io.OutputStream; import flex.messaging.io.MessageIOConstants; import flex.messaging.io.SerializationContext; import flex.messaging.io.amf.AmfMessageSerializer; import flex.messaging.io.amf.AmfTrace; public class Serializer extends AmfMessageSerializer { @Override public void initialize(SerializationContext context, OutputStream out, AmfTrace trace) { amfOut = new AMF0Output(context); amfOut.setOutputStream(out); amfOut.setAvmPlus(version >= MessageIOConstants.AMF3); debugTrace = trace; isDebug = trace != null; amfOut.setDebugTrace(debugTrace); } }

Manejo personalizado AMF 0

package ch.hedgesphere.core.blazeds.serialization; import flex.messaging.io.SerializationContext; public class AMF0Output extends flex.messaging.io.amf.Amf0Output { public AMF0Output(SerializationContext context) { super(context); } @Override protected void createAMF3Output() { avmPlusOutput = new AMF3Output(context); avmPlusOutput.setOutputStream(out); avmPlusOutput.setDebugTrace(trace); } }

Manejo personalizado de AMF 3

package ch.hedgesphere.core.blazeds.serialization; import java.io.IOException; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.joda.time.LocalTime; import flex.messaging.io.SerializationContext; public class AMF3Output extends flex.messaging.io.amf.Amf3Output { public AMF3Output(SerializationContext context) { super(context); } @Override public void writeObject(Object value) throws IOException { if(value instanceof DateTime) { value = convertToDate((DateTime)value); } if(value instanceof LocalDate) { value = convertToDate((LocalDate)value); } if(value instanceof LocalTime) { value = convertToDate((LocalTime)value); } super.writeObject(value); } private Object convertToDate(LocalTime time) { return time.toDateTimeToday().toDate(); } private Object convertToDate(LocalDate date) { return date.toDateMidnight().toDate(); } private Object convertToDate(DateTime dateTime) { return dateTime.toDate(); } }

Custom Marshaller para Flex-> Java Calling

package ch.hedgesphere.core.blazeds.translator; import org.joda.time.DateTime; import org.joda.time.LocalDate; import org.joda.time.LocalTime; import flex.messaging.io.amf.translator.ASTranslator; public class HedgesphereASTranslator extends ASTranslator { @SuppressWarnings({"rawtypes"}) @Override public Object convert(Object originalValue, Class type) { if( type.equals(DateTime.class)) { return convertToDateTime(originalValue); } if( type.equals(LocalDate.class)) { return convertToLocalDate(originalValue); } if( type.equals(LocalTime.class)) { return convertToLocalTime(originalValue); } return super.convert(originalValue, type); } private Object convertToLocalTime(Object originalValue) { return originalValue == null ? null : new LocalTime(originalValue); } private Object convertToLocalDate(Object originalValue) { return originalValue == null ? null : new LocalDate(originalValue); } private Object convertToDateTime(Object originalValue) { return originalValue == null ? null : new DateTime(originalValue); } @SuppressWarnings({"rawtypes"}) @Override public Object createInstance(Object source, Class type) { return super.createInstance(source, type); } }


Para las aplicaciones Java que utilizan el proyecto de integración Spring-BlazeDS de SpringSource, hay una manera mucho más simple de manejar esto:

  • Escriba una implementación de GenericConverter que maneja la asignación de ReadableDateTime a / desde java.util.Date.

  • Cree una subclase de AbstractAmfConversionServiceConfigProcessor y anule configureConverters, agregando la implementación de su convertidor al registro.

  • Actualice su configuración de Spring creando una instancia de ConfigProcessor y conectándola:

XML:

<flex:message-broker> <flex:config-processor ref="customConfigProcessor"/> </flex:message-broker>

Más información aquí:

http://static.springsource.org/spring-flex/docs/1.5.x/reference/html/index.html#amf-custom-converters