java - 通过 BlazeDS 从 Java 到 Flex 的自定义编码

标签 java apache-flex actionscript-3 blazeds jodatime

我的团队正在使用 BlazeDS 在基于 Spring 的服务器之上构建一个概念验证 Flex 应用程序。

我们进行了大量的日期计算,因此我们在整个代码和领域模型中广泛使用 Joda Time。

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

我们的目标是使用 Actionscript 3 数据类型 Date在 Flex 方面,并将该映射映射到我们对 Joda 时间的 DateTime 的使用, LocalDateLocalTime Java 端的类型。

我们可以解决Actionscript 3的转换问题Date使用插入 BlazeDS 的自定义类型编码器调用 Java 时的类型,但这似乎仅针对 Flex->Java/BlazeDS 方向调用,而不针对 Java/BlazeDS->Flex 方向调用。

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

另一个想法是实现Externalizable在我们的 Java DTO 上,但这似乎工作量太大,尤其是当我查看 BlazeDS 的竞争对手 GraniteDS 时,它显示在其文档中使用简单的类型转换器插入 Joda Time 支持!

任何想法表示赞赏。

最佳答案

好的 - 我自己找到了答案。这涉及编写我自己的 AMF 端点类 + 相关的序列化类。我得说那些人在http://flexblog.faratasystems.com是破解 BlazeDS 的重要灵感来源。

这段代码真的应该合并到 BlazeDS 本身或一些开源扩展项目中——它太基础了。

channel 定义

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

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

关于java - 通过 BlazeDS 从 Java 到 Flex 的自定义编码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4053003/

相关文章:

java - 通知点击事件而不显示 Activity ?

java - 是否有可用于 Java、C++ 和 JS 的可下载的 eclipse 包

apache-flex - 如何防止 TextField 中的向上/向下箭头默认行为?

apache-flex - 为什么 Facebook Actionscript API init() 不起作用?

actionscript-3 - 关于computeSpectrum() 和RTMP

actionscript-3 - ActionScript 3 : Do you need to remove EventListeners?

java - LinkedHashSet 迭代器无缘无故地进入无限循环

尝试创建自定义类的通用数组时发生 Java 转换错误

arrays - 数组与向量

java - 如何将默认单选选项处理为其他单选选项