1

Play 2.0 (Java) でのフォーム バインディングの国際化サポートの (悪い) 不足はありますか?

私たちのシステムは、少なくとも英語とポルトガル語をサポートする必要があります。これらは、日付に異なるパターン (dd/MM/yyyy または MM/dd/yyyy) を使用します。

一方、カスタムの日付形式を定義する方法は 1 つしか見つかりませんでした。それは、モデル クラスで注釈 (play.data.format.Formats.DateTime) を使用することです。形式はユーザーに依存するため、この場合の解決策ではありません。

application.conf で定義された date.format.[locale] パラメータは無視されているようですが、Formats.DateFormatter にはパターンが 1 つしかないため、これは驚くことではありません。

4

1 に答える 1

2

わかりました、私はついにこの「もの」が機能するようになりました。解決策は他の人に役立つかもしれません。私はフレームワークを悪用していないことをまだ100%確信していません...

(1) 一意のパターン (基本フレームワーク クラスなど) の代わりにマップ Locale/SimpleDateFormat を使用する独自の DateFormatter を作成しました。

Play Java の (もう 1 つの)バグのように思われるため、私のオーバーライドされた 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 に答える