Flex Java BlazeDS日期差

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flex Java BlazeDS日期差相关的知识,希望对你有一定的参考价值。

我正在尝试使用BlazeDS从Flex端向Java发送日期

flex中的字段类型

private var _scheduleDate:Date;

我已经用new Date()对其进行了初始化,并且如果发出警告,则在我的系统上显示正确的日期和时间。现在将对象发送到Java。日期被更改。

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

现在的转换部分:在flex上是

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

当我打印通过日期(在Java端)时,其

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

我已经读过很多博客等关于该解决方案的文章,他们将其称为时区问题,但我没有理解,如果客户端和服务器都在单个系统上,那么时区问题怎么可能导致此问题。

[Alert(flex)和带有新println(java)Date()在系统上显示正确的日期,因此时区问题是如何出现的。只有我能想到的是,BlazeDS导致了此问题。

在此链接中,他们引用了blazeDS的一些自定义封送处理,但超出了我的头Custom Marshalling from Java to Flex via BlazeDS

目前,我只有一个解决方案,此问题以纯文本而不是String对象的形式在Date中发送日期,并在Java端将String转换回Date对象。

是否有更好的解决方案,或者如果我的理解有任何问题,可以指出这一点。

谢谢,

答案

我建议以下解决方案。

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

Flex

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

Java

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

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

services-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输入/输出:

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

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

AMF0Output.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后端之间传递的所有日期都将被自动转换。 注意,您实际上是在更改日期

假设服务器时区为GMT + 6,客户端为GMT + 2 timezome。您正在从数据库中检索日期。 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。我们更改了日期。但是等效的字符串是相同的。

另一答案

此外,创建另一个与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();
    }
}

以上是关于Flex Java BlazeDS日期差的主要内容,如果未能解决你的问题,请参考以下文章

Flex+Java+Blazeds

在使用Flex Builder 3和BlazeDS时,如何解决“Server.processing”错误的“NullPointerException”?

Flex+BlazeDS+IntelliJ IDEA整合开发系列一之起步demo

为BlazeDS和AMF发送的请求添加自定义HTTP标头

由于未解决的依赖关系,grails install plugin blazeds 失败

登录 Flex Web 应用程序