2010-10-29 17 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