1

我是否(再次)遗漏了某些东西,或者 Play 2.0(Java)中的表单绑定缺乏(糟糕的)国际化支持?

我们的系统应该至少支持英语和葡萄牙语,它们使用不同的日期模式(dd/MM/yyyy 或 MM/dd/yyyy)。

另一方面,我只找到了一种定义自定义日期格式的方法:在模型类上使用注释(play.data.format.Formats.DateTime)。在我们的例子中不是一个解决方案,因为格式取决于用户

application.conf 中定义的任何 date.format.[locale] 参数似乎都被忽略了,这并不奇怪,因为 Formats.DateFormatter 只有一种模式。

4

1 回答 1

2

好的,我终于让这个“东西”工作了。该解决方案可能对其他人有用。我仍然不能 100% 确定我没有滥用框架......

(1) 我编写了自己的 DateFormatter,它使用地图 Locale/SimpleDateFormat 而不是独特的模式(如基础框架类)。

由于 Play Java 中似乎是(另一个)错误,我覆盖的 parse(String date, Locale locale) 忽略了 locale 参数并使用请求来获取首选语言。

这是完整的代码:

public class DateFormatter extends Formatters.SimpleFormatter<Date> {

    private Map<Locale, SimpleDateFormat> formats;
    private SimpleDateFormat defaultFormat;

    public DateFormatter(String defaultPattern) {
        formats = new HashMap<Locale, SimpleDateFormat>();      
        defaultFormat = new SimpleDateFormat(defaultPattern);
    }

    @Override
    public Date parse(String date, Locale locale) throws ParseException {

        Logger.debug("Parsing date " + date + " for locale " + locale);

        Context ctx = Context.current();
        if (ctx != null) {
            Lang preferred = Lang.preferred(ctx.request().acceptLanguages());
            Locale loc = preferred.toLocale();
            return getFormat(loc).parse(date);
        } else {
        return getFormat(locale).parse(date);
        }
    }

    @Override
    public String print(Date date, Locale locale) {
        return getFormat(locale).format(date);
    }

    public void addPattern(Locale locale, String pattern) {
        formats.put(locale, new SimpleDateFormat(pattern, locale));
    }

    private SimpleDateFormat getFormat(Locale locale) {
        SimpleDateFormat format = formats.get(locale);
        if (format == null)
            return defaultFormat;
        else
            return format;
    }   

}

(2) 此 DateFormatter 由应用程序全局对象在应用程序加载时配置和注册。

@Override
public void onStart(Application app) {

    registerDateFormatter(app);

}

/**
 * Registers a custom date formatter using configured
 * available languages and custom date formats.
 * 
 * Browses the locales defined in langs parameter and
 * for each one loads the date format defined in the
 * parameters custom.date.format.xx
 * 
 * Gets also the default (fallback) format defined in
 * date.format. If no one is defined uses an hard-coded
 * format yyyy-MM-dd
 */
private void registerDateFormatter(Application app) {

    Configuration config = app.configuration();

    // Get default format
    String defaultPattern = config.getString("date.format");
    if (defaultPattern == null)
        defaultPattern = "yyyy-MM-dd";

    DateFormatter formatter = new DateFormatter(defaultPattern);

    // Get date format from configuration
    for (Lang lang:    Lang.availables()) {
        Locale locale = lang.toLocale();
        String pattern = app.configuration().getString("custom.date.format." + lang.code());                        
        if (pattern != null)
            formatter.addPattern(locale, pattern);        
    }

    // Register the formatter for java.util.Date
    Formatters.register(Date.class, formatter);        
}

配置(在 application.conf 中)是:

# The application languages
# ~~~~~
application.langs="pt-br, en"
#
date.format="MM/dd/yyyy"
custom.date.format.en = "MM/dd/yyyy"
custom.date.format.pt-br = "dd/MM/yyyy"

(参数名称中需要custom.,直接使用date.format.xx会报错)

于 2012-07-16T12:02:50.677 回答