2

アプリの DateTime フィールドに JSON を投稿できるようにする魔法の言葉がわかりません。照会するとDateTime、エポックからのマイクロ秒として s が返されます。その形式で投稿しようとすると ( {"started":"1341006642000","task":{"id":1}})、「無効な値: 開始されました」と表示されます。

私もフィールドに追加@play.data.format.Formats.DateTime(pattern="yyyy-MM-dd HH:mm:ss")してstarted投稿しようとしまし{"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);
}

出力から、値が正しく受信されていることもわかります。これを機能させる方法を知っている人はいますか?

4

1 に答える 1

5

フォーム送信の処理ページの「カスタム DataBinder の登録」セクションとアプリケーションのグローバル設定ページを読み、この質問と比較した後、次の解決策を思いつきました。

オプションのformat 属性を使用してカスタム アノテーションを作成しました。

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 ディストリビューションに含まれているため、もっと簡単な方法があることを期待していましたが、これでうまくいきました。

Global注:クラスへの変更が検出されないように見えるため、Play アプリを再起動する必要があります。

于 2012-07-02T16:21:39.343 に答える