通过 BlazeDS 从 Java 到 Flex 的自定义编组

发布于 2024-09-29 23:31:35 字数 743 浏览 5 评论 0原文

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

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

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

我们的目标是在 Flex 端使用 Actionscript 3 数据类型 Date 并将其映射到我们对 Joda 时间的 DateTimeLocalDate 和Java 端的 LocalTime 类型。

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

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

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

任何想法表示赞赏。

My team are putting together a proof-of-concept Flex application sitting on top of a Spring-based server using BlazeDS.

We do quite a lot of date calculations, so we use Joda Time extensively throughout the code and in our domain model.

We're now trying to figure out how we can continue to use Joda Time in our DTOs that are sent back-and-forth with the Flex frontend via BlazeDS.

Our goal is to use the Actionscript 3 data type Date on the Flex side and have that map to our use of Joda time's DateTime, LocalDate and LocalTime types on the Java side.

We can solve the problem of converting Actionscript 3's Date type when calling Java with a custom type marshaller plugged into BlazeDS, but this appears to only be invoked for the Flex->Java/BlazeDS direction and not for the Java/BlazeDS->Flex direction.

I'm now looking at custom PropertyProxy implementations for BlazeDS, but this doesn't look like the right thing either.

The other idea was to implement Externalizable on our Java DTOs, but this seems like too much work, especially when I look at the BlazeDS rival GraniteDS and that shows plugging in Joda Time support in their documentation with a simple type converter!

Any ideas appreciated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

梦萦几度 2024-10-06 23:31:35

好的 - 我自己找到了答案。这涉及编写我自己的 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();
}   
}

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

OK - I've found the answer on my own. This involved writing my own AMF endpoint class + related serializing classes. I've gotta say that the guys over at http://flexblog.faratasystems.com have been a great source of inspiration on hacking BlazeDS.

This code should really be incorporated into BlazeDS itself or some Open Source extension project - it's so basic.

Channel Definition

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

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

    }

Custom Serializer

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

Custom AMF 0 Handling

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

Custom AMF 3 Handling

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

Custom Marshaller for Flex->Java Calling

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);
}
}
左耳近心 2024-10-06 23:31:35

对于使用 SpringSource 中的 Spring-BlazeDS 集成项目的 Java 应用程序,有一种更简单的处理方法:

  • 编写 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

For Java apps using the Spring-BlazeDS integration project from SpringSource, there is a much simpler way of handling this:

  • Write an implementation of GenericConverter that handles mapping ReadableDateTime to/from java.util.Date.

  • Create a subclass of AbstractAmfConversionServiceConfigProcessor and override configureConverters, adding your converter implementation to the registry.

  • Update your Spring configuration by creating an instance of your ConfigProcessor and wiring it up:

XML:

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

More info here:

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

迷爱 2024-10-06 23:31:35

您是否尝试过此博客中概述的自定义编组器方法:

http:// /flexblog.faratasystems.com/index.php/custom-type-masrhaller-in-blazeds

Have you tried the custom marshallers approach outlined on this blog:

http://flexblog.faratasystems.com/index.php/custom-type-masrhaller-in-blazeds

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文