Grails 无法将 JSON 中的日期/时间解组回 joda DateTime

Posted

技术标签:

【中文标题】Grails 无法将 JSON 中的日期/时间解组回 joda DateTime【英文标题】:Grails unable to unmarshall date/time from JSON back into joda DateTime 【发布时间】:2012-01-23 22:08:26 【问题描述】:

我在使用 Grails 的 JodaTime 插件时遇到问题。该插件似乎正确地将输出转换为 JSON,但是当返回相同的 JSON 对象时,它似乎无法再次接受输出的日期格式作为输入。

这些是我得到的错误:

Field error in object 'server.Session' on field 'lastUpdated': rejected value [2011-12-19T14:15:03-06:00]; codes [typeMismatch.server.Session.lastUpdated,typeMismatch.lastUpdated,typeMismatch.org.joda.time.DateTime,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [server.Session.lastUpdated,lastUpdated]; arguments []; default message [lastUpdated]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'org.joda.time.DateTime' for property 'lastUpdated'; nested exception is java.lang.IllegalArgumentException: Invalid format: "2011-12-19T14:15:03-06:00" is malformed at "11-12-19T14:15:03-06:00"]
Field error in object 'server.Session' on field 'dateCreated': rejected value [2011-12-19T14:15:03-06:00]; codes [typeMismatch.server.Session.dateCreated,typeMismatch.dateCreated,typeMismatch.org.joda.time.DateTime,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [server.Session.dateCreated,dateCreated]; arguments []; default message [dateCreated]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'org.joda.time.DateTime' for property 'dateCreated'; nested exception is java.lang.IllegalArgumentException: Invalid format: "2011-12-19T14:15:03-06:00" is malformed at "11-12-19T14:15:03-06:00"] id=33 version=0>

这是非常基本的领域模型:

package server

import org.joda.time.DateTime

class Session 

    DateTime dateCreated
    DateTime lastUpdated
    String ip

    static constraints = 
        ip blank: false
    

这里是 show 和 update 方法(分别发送和接收 JSON):

def show() 
    def sessionInstance = Session.get(params.id)
    if (!sessionInstance) 
        flash.message = message(code: 'default.not.found.message', args: [message(code: 'session.label', default: 'Session'), params.id])
        redirect(action: "list")
        return
    

    def response = [sessionInstance: sessionInstance]
    withFormat 
        html response
        json render response as JSON
        xml render response as XML
    


def update() 

    def sessionInstance = Session.get(params.id)
    if (!sessionInstance) 
        flash.message = message(code: 'default.not.found.message', args: [message(code: 'session.label', default: 'Session'), params.id])
        redirect(action: "list")
        return
    

    if (params.version) 
        def version = params.version.toLong()
        if (sessionInstance.version > version) 
            sessionInstance.errors.rejectValue("version", "default.optimistic.locking.failure",
                    [message(code: 'session.label', default: 'Session')] as Object[],
                    "Another user has updated this Session while you were editing")
            render(view: "edit", model: [sessionInstance: sessionInstance])
            return
        
    

    sessionInstance.properties = params // <----- This is what causes the errors

    log.info("instance: $sessionInstance.dump()") // <------ This is where I'm seeing the error messages

    if (!sessionInstance.save(flush: true)) 
        render(view: "edit", model: [sessionInstance: sessionInstance])
        return
    

    flash.message = message(code: 'default.updated.message', args: [message(code: 'session.label', default: 'Session'), sessionInstance.id])
    redirect(action: "show", id: sessionInstance.id)

我不确定我需要做什么来纠正这个问题,或者即使我做的事情正确,因为我对 Grails 还很陌生。实际上,引起问题的两个日期字段应该由 GORM 内部 100% 处理,我宁愿控制器完全忽略它们,但是一旦域模型获得,就会有其他类似的日期字段需要更新填写。

如何获得自动 JSON 解组以正确转换回 joda 时间 DateTime 对象?

注意:这目前是客户端-服务器应用程序的概念验证。

【问题讨论】:

【参考方案1】:

我不确定原因,也不确定为什么此修复程序有效,但是将 jodatime.format.html5 = true 添加到 Config.groovy 文件可以使一切正常。

据我所知,JSON 输出没有任何变化,但无论出于何种原因,它都会使 JSON 输入处理和数据绑定工作。

甚至暗示这一点的唯一类似文档是here。

尝试通过jodatime.format.org.joda.time.DateTime = "yyyy-MM-dd'T'HH:mm:ss.SSSZZ" 之类的方式设置DateTime 的格式根本没有效果。

【讨论】:

以上是关于Grails 无法将 JSON 中的日期/时间解组回 joda DateTime的主要内容,如果未能解决你的问题,请参考以下文章

从 json 文件中解析 grails 中的日期

使用 Grails 在服务器端获取 JSON 数据

无法将字符串解组为 int64 类型的 Go 值

json:无法将字符串解组为 MyMap.map 类型的 Go 值

json 错误,无法将对象解组为 Go 值

恐慌:json:无法将数组解组为 main.Structure 类型的 Go 值