2010-10-29 16 views
6

我的团队正在使用BlazeDS将基于Spring的服务器放在一个概念验证Flex应用程序中。通过BlazeDS从Java到Flex的自定义编组

我们做了很多日期计算,所以我们在整个代码和我们的领域模型中广泛使用Joda时间。

我们现在试图弄清楚我们如何在我们的DTO中继续使用Joda Time,这些Doda是通过BlazeDS与Flex前端来回发送的。

我们的目标是用在Flex端的ActionScript 3的数据类型Date并具有映射到我们在Java端使用乔达时间的DateTimeLocalDateLocalTime类型。

我们可以通过插入BlazeDS的自定义类型编组调用Java来调用Java,但是这似乎只能调用Flex-> Java/BlazeDS方向,而不是Java/BlazeDS方法来转换Actionscript 3的Date类型 - >灵活方向。

我现在正在查看BlazeDS的自定义PropertyProxy实现,但这看起来并不是正确的事情。

另一个想法是落实我们的Java DTO的Externalizable,但是这似乎有太多的工作,尤其是当我看到BlazeDS的对手GraniteDS的,并显示封堵约达时间支持他们的文档在一个简单的类型转换器!

任何想法赞赏。

回答

15

行 - 我发现我自己的答案。这涉及编写我自己的AMF端点类+相关的序列化类。我必须说,在http://flexblog.faratasystems.com这些家伙一直是黑客入侵BlazeDS的灵感来源。

这段代码应该真的被整合到BlazeDS本身或某个开源扩展项目中 - 这非常基础。

频道定义

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

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

    } 

自定义序列

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

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

定制的Marshaller为Flex->的Java调用

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

对于Java应用使用的是从SpringSource的Spring的,BlazeDS的集成项目,有处理这个更简单的方法:

  • 写GenericConverter的实现,处理映射ReadableDateTime从java.util.Date到/。

  • 创建AbstractAmfConversionServiceConfigProcessor的子类并覆盖configureConverters,将转换器实现添加到注册表中。

  • 更新通过创建ConfigProcessor的一个实例,连线你的Spring配置:

XML:

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

此处了解详情:

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

+0

这看起来很值得调查。自从我们添加了一个BigDecimal实现并给出了我们需要编写的代码(低级别的东西)之后,如果这会插入到Springs impl中,我会感到惊讶。 – SteveD 2011-08-17 12:36:17

+0

如果您有任何问题,请随时在Twitter上向我咨询。我很惊讶这是多么容易。 – 2011-08-17 13:05:53