2010-10-29 6 views
6

Mon équipe met en place une application Flex de preuve de concept sur un serveur Spring utilisant BlazeDS. Nous faisons beaucoup de calculs de date, donc nous utilisons beaucoup Joda Time dans tout le code et dans notre modèle de domaine.Personnalisation de Java vers Flex via BlazeDS

Nous essayons maintenant de comprendre comment nous pouvons continuer à utiliser Joda Time dans nos DTO qui sont envoyés dans les deux sens avec le frontend Flex via BlazeDS.

Notre objectif est d'utiliser sur le côté Flex 3 Actionscript le type de données Date et ont cette carte à notre utilisation de DateTime, LocalDate et LocalTime les types de temps Joda sur le côté Java. Nous pouvons résoudre le problème de la conversion du type Date d'Actionscript 3 lors de l'appel de Java avec un marshaller de type personnalisé branché sur BlazeDS, mais cela ne semble être invoqué que pour la direction Flex-> Java/BlazeDS et non pour Java/BlazeDS -> Direction Flex.

Je regarde maintenant les implémentations personnalisées PropertyProxy pour BlazeDS, mais cela ne semble pas non plus être la bonne chose. L'autre idée était de mettre en œuvre Externalizable sur nos DTO Java, mais cela semble être trop de travail, surtout quand je regarde le concurrent BlazeDS GraniteDS et qui montre le support de Joda Time dans leur documentation avec un simple convertisseur de type!

Toutes les idées ont été appréciées.

Répondre

15

OK - j'ai trouvé la réponse moi-même. Cela impliquait d'écrire ma propre classe de point de terminaison AMF + les classes de sérialisation associées. Je dois dire que les gars de http://flexblog.faratasystems.com ont été une grande source d'inspiration pour le piratage de BlazeDS.

Ce code devrait vraiment être incorporé dans BlazeDS lui-même ou dans un projet d'extension Open Source - c'est tellement basique.

canal Définition

<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> 

AMF sur mesure Endpoint

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(); 
     } 

    } 

sur mesure sérialiseur

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); 
    } 
} 

AMF sur mesure 0 Manipulation

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); 
    } 
} 

AMF sur mesure 3 Manipulation

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(); 
} 
} 

personnalisés Marshaller pour Flex-> Java Appel

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); 
} 
} 
1

Pour les applications Java à l'aide du projet d'intégration printemps-BlazeDS de SpringSource, il existe un moyen beaucoup plus simple de gérer cette :

  • écrire une implémentation de GenericConverter qui gère ReadableDateTime de cartographie à/de java.util.Date.

  • Créez une sous-classe de AbstractAmfConversionServiceConfigProcessor et remplacez configureConverters, en ajoutant votre implémentation de convertisseur dans le registre.

  • Mettez à jour votre configuration Spring en créant une instance de votre ConfigProcessor et le câblage vers le haut:

XML:

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

Plus d'infos ici:

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

+0

Cela semble intéressant d'enquêter. Nous avons depuis ajouté une implémentation BigDecimal et étant donné le code dont nous avions besoin pour écrire (stuff de bas niveau), je serais surpris si cela se branche sur Springs impl. – SteveD

+0

Si vous avez des questions, n'hésitez pas à me le faire savoir sur Twitter. J'ai été surpris de voir à quel point cela était facile à implémenter. –

Questions connexes