Play Framework 2.0: Custom formatters

2019-02-13 18:12发布

问题:

I'm trying to write a custom formatter (for DateTime fields, as opposed to java.util.Date fields), but am having a hard time getting this to work. I've created my annotation, as well as extended the AnnotationFormatter class. I call play.data.format.Formatters.register(DateTime.class, new MyDateTimeAnnotationFormatter()) on Application load, but the parse and print methods never trigger.

How am I supposed to do this?

Edit: the code in question might be helpful ;)

The annotation class (heavily inspired by the annotation class included with Play Framework):

@Target({ FIELD })
@Retention(RUNTIME)
@play.data.Form.Display(name = "format.datetime", attributes = { "pattern" })
public static @interface JodaDateTime {
    String pattern();
}

The custom formatter class:

public static class AnnotationDateTimeFormatter extends AnnotationFormatter<JodaDateTime, DateTime> {

    @Override
    public DateTime parse(JodaDateTime annotation, String text, Locale locale) throws ParseException {
        if (text == null || text.trim().isEmpty()) {
            return null;
        }

        return DateTimeFormat.forPattern(annotation.pattern()).withLocale(locale).parseDateTime(text);
    }

    @Override
    public String print(JodaDateTime annotation, DateTime value, Locale locale) {
        if (value == null) {
            return null;
        }

        return value.toString(annotation.pattern(), locale);

    }

To register the formatter with the framework, I make this call in a static initalizer on the Application class (there might very well be a better place to put this, feel free to tell me where):

play.data.format.Formatters.register(DateTime.class, new AnnotationDateTimeFormatter());

I've confirmed by single-stepping through the debugger that this call gets made and that no errors are thrown, yet still the formatter isn't run in spite of annotating the DateTime fields appropriately like this:

@Formats.JodaDateTime(pattern = "dd.MM.yyyy HH:mm:ss")
public DateTime timeOfRequest = new DateTime();

I'm at loss here.

回答1:

You need to register for JodaDateTime instead of DateTime.

play.data.format.Formatters.register(JodaDateTime.class, new AnnotationDateTimeFormatter());


回答2:

I had a similar problem with a formatter for DateTime. I was registering the formatter from my Global.onStart as described here. It appears simply creating the Global class didn't trigger a reload. Once I modified another file which triggered a reload (shown as --- (RELOAD) --- in the console output) it started working. Stopping and restarting your app should have the same effect.