【问题标题】:Unmarshalling JSON to Groovy in Grails Date在 Grails Date 中将 JSON 解组为 Groovy
【发布时间】:2015-06-10 09:37:08
【问题描述】:

我正在使用 Grails 2.4 和 Ajax。在客户端,我构建 JSON 数据如下:

var data = {
    // ... not important
    date: new Date(
            parseInt($("#date_year").val()),
            parseInt($("#date_month").val()) - 1,
            parseInt($("#date_day").val())),
    // ...
};

我用 jQuery Ajax 发送日期:

$.ajax({
    url: '${createLink(controller: 'report', action: 'save')}',
    type: 'POST',
    data: JSON.stringify(data),
    contentType: 'application/json; charset=utf-8',
    success: function (respondData, textStatus, jqXHR) {
        alert('Saved succesfully');
    },
    error: function(jqXHR, textStatus, errorThrown) {
        alert('NOT SAVED!!!');
    }
});

在报表控制器ReportController 我有操作save(ThreatReport report)。通过某种魔法,Grails 能够将 JSON 数据解组到由 ThreatReport report 参数表示的 Groovy 模型(如果有人会指出一些关于如何配置的文档,我将非常感激)。 ThreatReport 类有一个 Date 属性(和其他属性,但它们工作正常)。然而,Grails 似乎在转换这个日期时遇到了麻烦。在 JavaScript 中我得到了

Wed Jun 10 2015 00:00:00 GMT+0200 (Central Europe Daylight Time)

然而,在 Groovy 控制器中,它突然回到了一天:

Tue Jun 09 00:00:00 CEST 2015

正如我所说,其余属性已正确转换。

【问题讨论】:

  • 我不推荐使用 JavaScripts toString() 来序列化日期。我会使用momentjs 之类的东西来格式化日期字符串并使用相同的格式模式对其进行反序列化。
  • 你是指JSON.stringify(data)吗?
  • 不是真的 - 在你的数据中我会做 var data {... 'date': date.getTime()} 并将其转换回时间 (new Date(jsonDateValue))
  • 我不认为我理解你。我有三个数字,一年,一个月和一天。从这些数字中,我创建了一个日期,如上所示。所以你的意思是我应该像我一样创建日期,然后使用date.getTime() 并使用new Date(jsonDateValue) 将其重新转换回来?这对它有什么帮助?当我使用帮助打印时,date 中的日期是正确的。 jQuery 发送正确的日期。只有 Groovy 对象包含早于一天的日期。
  • 目前我使用了一种解决方法——我故意在将它发送到服务器之前增加一天(例如,当我想要 10/6 月时,我发送 11/6 月),但这看起来真的很笨拙和丑陋的。更不用说我不知道​​它是否适用于所有情况。

标签: jquery ajax json grails


【解决方案1】:

我之前在 Java 中遇到过时区问题,您是否已经尝试将 -Duser.timezone 作为 JVM 启动的参数?

http://en.wikipedia.org/wiki/List_of_tz_database_time_zones

例子:

...java -Duser.timezone=Europe/London

或者(不确定这是否有效)

...java -Duser.timezone=Etc/GMT+2

更新

java测试代码

Date date = new Date("2015/6/10");
System.out.println(date);
DateTime date2 = new DateTime(date.getTime(), DateTimeZone.UTC);
System.out.println(date2);

产生输出

Wed Jun 10 00:00:00 CEST 2015
2015-06-09T22:00:00.000Z

作为由于时区和/或 DST 问题导致的日期切换问题的示例(在我的情况下,测试 JVM 使用我正确的时区 GMT+2,所以我在第二个日期强制使用 UTC,时间戳从第一个日期开始) .

也许这不是您的具体问题,但是当您将正确的时区作为参数传递给 Web 应用程序服务器 的 JVM(例如在 tomcat 启动脚本中,不在您的 IDE 中)。例如,当您在欧洲实行夏令时时,请尝试“Etc/GMT+2”。

这一定不是但可能是您问题的根源,我不熟悉您使用的框架,但我知道时区和夏令时问题可能很复杂/令人困惑,因为它可能是自定义和默认设置的混搭(操作系统、JVM)以及框架如何处理带/不带时间和/或时区的日期。

如果有帮助,请不要忘记为您的应用程序调整其他系统上的 JVM 调用关于时区参数:-)

【讨论】:

  • 我已经尝试将它添加到 IntelliJ Idea 中的配置中,但它似乎没有做出任何改变。无论如何,它只改变一天,所以我不确定时区如何影响它..
  • 经过进一步检查,我可以说服务器和客户端都使用相同的时区..似乎问题在于解组..无论如何,不​​会改变几个小时的时间,因为我会期望在不同时区的情况下,但总是一天,一整天。如果我能找到更多信息,我会告诉你。无论如何,谢谢你的努力:)
【解决方案2】:

好的,所以我终于找到了解决方案。它连接到时区。但是,问题似乎出在浏览器 + 我的 Grails 配置中。浏览器将日期序列化为 zulu 时区中的字符串,这意味着在我的时区 (+02:00) 创建日期后,例如 13. May 1999 00:00:00 它将被序列化为 12. May 1999 22: 00:00。但是,Grails 被设置为只解析日期而不是时间,所以最后我在服务器端得到了 12. May 1999 00:00:00。然后它似乎是24小时轮班。现在我使用自己的简单代码将其直接序列化为正确的 ISO 日期:

var data = {
    // ... not important
    date: $("#date_year").val() + "-" + $("#date_month").val() + "-" + $("#date_day").val(),
    // ...
};

所以它会变成一个字符串“1999-5-13”。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    • 1970-01-01
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多