问题
I'm having trouble using the JodaTime plugin for Grails. The plugin seems to be correctly converting to JSON for the output, but it does not seem to be able to accept the outputted date format again as input when the same JSON object is sent back in.
These are the errors I get:
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>
Here's the very basic domain model:
package server
import org.joda.time.DateTime
class Session {
DateTime dateCreated
DateTime lastUpdated
String ip
static constraints = {
ip blank: false
}
}
And here are the show and update methods (send and receive JSON respectively):
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)
}
I'm not sure what I need to do to correct this, or even if I'm doing things correctly, since I'm very new to Grails. In all reality, the two date fields that are causing issues should be handled 100% internally by GORM and I would rather the controller ignore them completely, but there will be other date fields like them that will need to be updated once the domain model gets filled in.
How can I get the automatic JSON unmarshalling to correctly convert back into joda time DateTime objects?
Note: This is currently a proof-of-concept for a client-server application.
回答1:
I'm not sure of the cause, nor why this fix works, but adding jodatime.format.html5 = true
to the Config.groovy file makes everything work.
As far as I can tell, there is no change in the JSON output, but for whatever reason, it makes the JSON input handling and data binding work.
The only semblance of documentation that even hints at this is here.
Trying to set the format for DateTime
via something like jodatime.format.org.joda.time.DateTime = "yyyy-MM-dd'T'HH:mm:ss.SSSZZ"
had no effect at all.
来源:https://stackoverflow.com/questions/8567078/grails-unable-to-unmarshall-date-time-from-json-back-into-joda-datetime