2

我正在尝试使用 BlazeDS 将日期从 flex 端发送到 java

flex 中的字段类型

private var _scheduleDate:Date;

我已经用 初始化了它new Date(),如果提醒它,正确的日期和时间会显示在我的系统上。现在当对象被发送到java时。日期变了。

请注意我的 flex 应用程序和 java(JBoss 服务器在同一台机器上运行)。如果我在用 初始化的 java 端独立打印日期new Date(),它也会显示系统的正确日期。

现在转换部分:在 flex 上是

25/04/2013 12:30 PM(如警报所示)

当我打印这个过去的日期(在java端)时,它

25/04/2013 02:30 PM(时差 2 小时)

我已经阅读了许多博客等以获取解决方案,他们将其称为时区问题,但我不明白,如果客户端和服务器都在单个系统上,时区问题怎么会导致这个问题。

Alert(flex)并且println(java)随着系统的新Date()显示正确日期,那么时区问题是如何出现的。只有我能想到的是,BlazeDS 导致了这个问题。

在此链接中,他们为 blazeDS 引用了一些自定义编组,但它超出了我的想象, 自定义编组通过 BlazeDS 从 Java 到 Flex

现在,对于这个问题,我只有一个解决方案,可以将日期String作为纯文本而不是Date对象发送,然后在 java 端转换StringDate对象。

有没有更好的解决方案,或者如果我的理解有任何问题,请有人指出。

谢谢,

4

2 回答 2

2

我建议以下解决方案。

首先,发送客户端时区偏移并将其存储为会话属性。

柔性

ro.setClientTimezoneOffset(-new Date().getTimezoneOffset() * 60 * 1000);

爪哇

public void setClientTimezoneOffset(Long t) {
    FlexContext.getFlexSession().setAttribute("clientTimezoneOffset", t);
}

创建我们自己的扩展端点类flex.messaging.endpoints.AMFEndpoint并将其指向通道定义:

服务-config.xml

<channel-definition id="my-amf"
            class="mx.messaging.channels.AMFChannel">
    <endpoint url="http://{server.name}:{server.port}/{context.root}/messagebroker/amf" 
                class="com.package.AMFEndpoint"/>
</channel-definition>

AMFEndpoint.java

package com.package;

public class AMFEndpoint extends flex.messaging.endpoints.AMFEndpoint {

    @Override
    protected String getSerializerClassName() {
        return Serializer.class.getName();
    }

    @Override
    protected String getDeserializerClassName() {
        return Deserializer.class.getName();
    }
}

扩展 amf 串行器、解串器、amf 输入/输出:

序列化器.java

package com.package;

import flex.messaging.io.MessageIOConstants;
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.AmfMessageSerializer;
import flex.messaging.io.amf.AmfTrace;

import java.io.OutputStream;

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

反序列化器.java

package com.package;

import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.AmfMessageDeserializer;
import flex.messaging.io.amf.AmfTrace;

import java.io.InputStream;

public class Deserializer extends AmfMessageDeserializer {
    @Override
    public void initialize(SerializationContext context, InputStream in, AmfTrace trace) {
        amfIn = new AMF0Input(context);
        amfIn.setInputStream(in);

        debugTrace = trace;
        isDebug = debugTrace != null;
        amfIn.setDebugTrace(debugTrace);
    }
}

AMF0Input.java

package com.package;

import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf0Input;

import java.io.IOException;

public class AMF0Input extends Amf0Input {
    public AMF0Input(SerializationContext context) {
        super(context);
    }

    @Override
    public Object readObject() throws ClassNotFoundException, IOException {
        if (avmPlusInput == null) {
            avmPlusInput = new AMF3Input(context);
            avmPlusInput.setDebugTrace(trace);
            avmPlusInput.setInputStream(in);
        }
        return super.readObject();
    }
}

AMF0输出.java

package com.package;    

import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf0Output;

public class AMF0Output extends Amf0Output {
    public AMF0Output(SerializationContext context) {
        super(context);
    }

    @Override
    protected void createAMF3Output()
    {
        avmPlusOutput = new AMF3Output(context);
        avmPlusOutput.setOutputStream(out);
        avmPlusOutput.setDebugTrace(trace);
    }
}

最后,您扩展 amf 3 输入/输出类,其中日期被序列化和反序列化。您应用偏移差异。

AMF3Input.java

package com.package;

import flex.messaging.FlexContext;
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf3Input;

import java.io.IOException;
import java.util.Date;

public class AMF3Input extends Amf3Input {
    @Override
    protected Date readDate() throws IOException {
        Date d = super.readDate();
        if (d != null) {
            Long clientOffset = (Long) FlexContext.getFlexSession().getAttribute("clientTimezoneOffset");
            Long serverOffset = (Long) (-d.getTimezoneOffset() * 60L * 1000);
            d.setTime(d.getTime() - (serverOffset - clientOffset));
        }
        return d;
    }

    public AMF3Input(SerializationContext context) {
        super(context);
    }
}

AMF3Output.java

package com.package;

import flex.messaging.FlexContext;
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.Amf3Output;

import java.io.IOException;
import java.util.Date;

public class AMF3Output extends Amf3Output {
    public AMF3Output(SerializationContext context) {
        super(context);
    }

    @Override
    protected void writeAMFDate(Date d) throws IOException {
        if (d != null) {
            Long clientOffset = (Long) FlexContext.getFlexSession().getAttribute("clientTimezoneOffset");
            Long serverOffset = (Long) (-d.getTimezoneOffset() * 60L * 1000);
            d.setTime(d.getTime() + (serverOffset - clientOffset));
        }
        super.writeAMFDate(d);
    }
}

现在,在 Flex 前端和 BlazeDS 后端之间传递的所有日期都将自动转换。请注意,您实际上更改了 date

假设服务器时区为 GMT+6,客户端为 GMT+2 时区。您正在从数据库中检索日期。java 上的日期是01.01.2013 10.00.00 GMT+6,通常 flex 会得到01.01.2013 06.00.00 GMT+2。这是相同的日期,但等效的字符串不同。在我们的例子中 flex 会得到01.01.2013 10.00.00 GMT+2. 我们更改了日期。但是字符串等价物是相同的。

于 2013-04-25T16:16:14.520 回答
0

另外创建另一个类以与以前的 Java 版本兼容:

package br.com.ultreia.flex;

import java.io.OutputStream;

import flex.messaging.io.MessageIOConstants;
import flex.messaging.io.SerializationContext;
import flex.messaging.io.amf.AmfTrace;

public class Java15AmfMessageSerializer extends flex.messaging.io.amf.Java15AmfMessageSerializer{
    @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);
    }
}

我改变了AMFEndpoint.java类

public class AMFEndpoint extends flex.messaging.endpoints.AMFEndpoint {

    public AMFEndpoint(){
        super();
    }

    @Override
    protected String getSerializerClassName() {
        return Serializer.class.getName();
    }

    @Override
    protected String getSerializerJava15ClassName() {
        return Java15AmfMessageSerializer.class.getName();
    }

    @Override
    protected String getDeserializerClassName() {
        return Deserializer.class.getName();
    }
}
于 2019-11-06T21:08:21.163 回答