2

我无法弄清楚在我的应用程序中为发布日期时间字段发布JSON的魔法词。当查询时,DateTimes自时代起以微秒为单位返回。当我尝试以该格式发布时({"started":"1341006642000","task":{"id":1}}),我收到“无效值:已启动”。从JSON反序列化回到播放2.0中的joda DateTime

我也尝试在started字段中添加@play.data.format.Formats.DateTime(pattern="yyyy-MM-dd HH:mm:ss")字段,并发布了{"started":"2012-07-02 09:24:45","task":{"id":1}},它们的结果相同。

控制器的方法是:

@BodyParser.Of(play.mvc.BodyParser.Json.class) 
public static Result create(Long task_id) { 
    Form<Run> runForm = form(Run.class).bindFromRequest(); 
    for (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); 
} 

我还可以从输出正在正确地接收的值看到。任何人都知道如何使这项工作?

回答

5

Application global settings页面一起阅读Handling form submission页的“注册自定义的DataBinder”部分,并与this question比较后,我想出了以下解决方案:

我创建了一个自定义的注释与可选格式属性:

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 ""; 
} 

和登记从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); 
       } 

     }); 
    } 

} 

如果需要,您可以指定一种格式,或者默认情况下它将使用自纪元以来的毫秒数。我希望自从Joda被包含在Play发行版中以后,会有一种更简单的方式,但是这样做能够实现。

注意:您需要重新启动您的Play应用程序,因为它似乎没有检测到Global类的更改。