playframework - Deserializing from JSON back to joda DateTime in Play 2.0 -
i can't figure out magic words allow posting json datetime field in app. when queried, datetime
s returned microseconds since epoch. when try post in format though ({"started":"1341006642000","task":{"id":1}}
), "invalid value: started".
i tried adding @play.data.format.formats.datetime(pattern="yyyy-mm-dd hh:mm:ss")
started
field , posting {"started":"2012-07-02 09:24:45","task":{"id":1}}
had same result.
the controller method is:
@bodyparser.of(play.mvc.bodyparser.json.class) public static result create(long task_id) { form<run> runform = form(run.class).bindfromrequest(); (string key : runform.data().keyset()) { system.err.println(key + " => " + runform.apply(key).value() + "\n"); } if (runform.haserrors()) return badrequest(runform.errorsasjson()); run run = runform.get(); run.task = task.find.byid(task_id); run.save(); objectnode result = json.newobject(); result.put("id", run.id); return ok(result); }
i can see output values being received correctly. know how make work?
after reading "register custom databinder" section of handling form submission page along application global settings page , comparing this question came following solution:
i created custom annotation optional format attribute:
package models; import java.lang.annotation.*; @target({ elementtype.field }) @retention(retentionpolicy.runtime) @play.data.form.display(name = "format.joda.datetime", attributes = { "format" }) public @interface jodadatetime { string format() default ""; }
and registered custom formatter onstart
:
import java.text.parseexception; import java.util.locale; import org.joda.time.datetime; import org.joda.time.format.datetimeformat; import play.*; import play.data.format.formatters; public class global extends globalsettings { @override public void onstart(application app) { formatters.register(datetime.class, new formatters.annotationformatter<models.jodadatetime,datetime>() { @override public datetime parse(models.jodadatetime annotation, string input, locale locale) throws parseexception { if (input == null || input.trim().isempty()) return null; if (annotation.format().isempty()) return new datetime(long.parselong(input)); else return datetimeformat.forpattern(annotation.format()).withlocale(locale).parsedatetime(input); } @override public string print(models.jodadatetime annotation, datetime time, locale locale) { if (time == null) return null; if (annotation.format().isempty()) return time.getmillis() + ""; else return time.tostring(annotation.format(), locale); } }); } }
you can specify format if want, or use milliseconds since epoch default. hoping there simpler way since joda included play distribution, got things working.
note: you'll need restart play app doesn't seem detect changes global
class.
Comments
Post a Comment