6


7

BlazeDSを介したJavaからFlexへのカスタムマーシャリング

私のチームは、BlazeDSを使用して、Springベースのサーバー上に概念実証のFlexアプリケーションを配置しています。

私たちは非常に多くの日付計算を行うため、コード全体およびドメインモデルでJoda Timeを広範囲に使用します。

現在、BlazeDS経由でFlexフロントエンドとやり取りされるDTOでJoda Timeを使用し続ける方法を見つけようとしています。

Flex側でActionscript 3データ型「Date」を使用し、Java側でJoda時間の「DateTime」、「LocalDate」、および「LocalTime」型の使用にマップするようにすることが目標です。

BlazeDSにプラグインされたカスタムタイプマーシャラーでJavaを呼び出すときにActionscript 3の `Date`タイプを変換する問題を解決できますが、これはFlex→ Java / BlazeDS方向に対してのみ呼び出され、Java / BlazeDS→に対しては呼び出されないようですフレックス方向。

私は現在、BlazeDSのカスタム `PropertyProxy`実装を検討していますが、これも正しいことのようには見えません。

もう1つのアイデアは、Java DTOに「外部化可能」を実装することでしたが、特にBlazeDSのライバルであるGraniteDSを見ると、単純な型コンバーターを使用してドキュメントにJoda Timeサポートをプラグインしているので、これは非常に手間がかかりそうです!

任意のアイデアは大歓迎です。

3 Answer


15


OK-自分で答えを見つけました。 これには、独自のAMFエンドポイントクラスと関連するシリアル化クラスを記述する必要がありました。 http://flexblog.faratasystems.comにいる人たちはBlazeDSのハッキングに関する素晴らしいインスピレーションの源となっていると言わざるを得ません。

このコードは、BlazeDS自体またはいくつかのオープンソース拡張プロジェクトに実際に組み込む必要があります-それはとても基本的なものです。

チャンネル定義

                ch.hedgesphere.core.blazeds.translator.HedgesphereASTranslator

カスタム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();
}
}

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


SpringSourceのSpring-BlazeDS統合プロジェクトを使用するJavaアプリの場合、これを処理するはるかに簡単な方法があります。

  • マッピングを処理するGenericConverterの実装を書く java.util.DateとのReadableDateTime。

  • AbstractAmfConversionServiceConfigProcessorのサブクラスを作成し、 configureConvertersをオーバーライドして、レジストリーにコンバーター実装を追加します。

  • インスタンスを作成してSpring構成を更新します ConfigProcessorと接続:

XML:


詳細はこちら:


0


このブログで概説されているカスタムマーシャラーアプローチを試しましたか?