Play framework 国际化
程序员文章站
2022-06-08 12:50:27
...
Play的国际化操作还是非常简单的。大概分为四步:
1. 首先在${project_home}/conf/application.conf中定义你要用到的哪些国际化语言
2. 在${project_home}/conf/下新建两个 message 文件,后缀名跟上面定义的语言一样。
message.en
message.zh
3. 在模板文件里调用这些message
4. 在你的程序启动的时候进行国际化的设置(如果不设置,Play框架会有一套自己的解决方案)
PS:启动程序之后,你可以在页面上写一个改变国际化语言的按钮,后台处理的时候也是调用这个 Lang.set(locale).
我们来看看Play.Lang类的源代码
不难看出,Play在获取国际化设置的时候大概是这么处理的:
1.首先从 ThreadLocal 中获取,这个地方是由开发者在代码手动 set 的,也就是 Lang.set("zh")这样的。
2.如果 ThreadLocal 没有,则框架会自己去尝试解决,首先会从 Cookie 中获取,如果没有就从 HTTP 请求中获取 Header 的 accept-language 。如果还没有,那么就会去做一个默认的设置。默认的设置规则是:如果 application.conf 有定义的话,那么取第一个,如果没有,那么设置为空字符串“”。
以上的整个过程仅是我个人见解,欢迎指正:)
PS:eweb4j也马上要支持国际化啦。
application.langs=en,zh
message.en message.zh
message.en
welcome = Welcome to China
message.zh
welcome = 欢迎来到中国
<h1>&{welcome}</h1>
Lang.set("zh")//设置为中文
PS:启动程序之后,你可以在页面上写一个改变国际化语言的按钮,后台处理的时候也是调用这个 Lang.set(locale).
package play.i18n; import java.util.Locale; import play.Logger; import play.Play; import play.mvc.Http; import play.mvc.Http.Request; import play.mvc.Http.Response; /** * Language support */ public class Lang { public static ThreadLocal<String> current = new ThreadLocal<String>(); /** * Retrieve the current language or null * @return The current language (fr, ja, it ...) or null */ public static String get() { String locale = current.get(); if (locale == null) { // don't have current locale for this request - must try to resolve it Http.Request currentRequest = Http.Request.current(); if (currentRequest!=null) { // we have a current request - lets try to resolve language from it resolvefrom( currentRequest ); } else { // don't have current request - just use default setDefaultLocale(); } // get the picked locale locale = current.get(); } return locale; } /** * Force the current language * @param locale (fr, ja, it ...) * @return false if the language is not supported by the application */ public static boolean set(String locale) { if (locale.equals("") || Play.langs.contains(locale)) { current.set(locale); return true; } else { Logger.warn("Locale %s is not defined in your application.conf", locale); return false; } } /** * Clears the current language - This wil trigger resolving language from request * if not manually set. */ public static void clear() { current.remove(); } /** * Change language for next requests * @param locale (fr, ja, it ...) */ public static void change(String locale) { if (set(locale)) { Response.current().setCookie(Play.configuration.getProperty("application.lang.cookie", "PLAY_LANG"), locale); } } /** * Guess the language for current request in the following order: * [list=1] * [*]if a <b>PLAY_LANG</b> cookie is set, use this value * [*]if <b>Accept-Language</b> header is set, use it only if the Play! application allows it.<br/>supported language may be defined in application configuration, eg : [i]play.langs=fr,en,de)[/i] * <li>otherwise, server's locale language is assumed * [/list] * @param request */ private static void resolvefrom(Request request) { // Check a cookie String cn = Play.configuration.getProperty("application.lang.cookie", "PLAY_LANG"); if (request.cookies.containsKey(cn)) { String localeFromCookie = request.cookies.get(cn).value; if (localeFromCookie != null && localeFromCookie.trim().length()>0) { if (set(localeFromCookie)) { // we're using locale from cookie return; } // could not use locale from cookie - clear the locale-cookie Response.current().setCookie(cn, ""); } } // Try from accept-language - look for an exact match for (String a: request.acceptLanguage()) { a = a.replace("-", "_").toLowerCase(); for (String locale: Play.langs) { if (locale.toLowerCase().equals(a)) { set(locale); return; } } } // now see if we have a country-only match for (String a: request.acceptLanguage()) { if (a.indexOf("-") > 0) { a = a.substring(0, a.indexOf("-")); } for (String locale: Play.langs) { if (locale.equals(a)) { set(locale); return; } } } // Use default setDefaultLocale(); } public static void setDefaultLocale() { if (Play.langs.isEmpty()) { set(""); } else { set(Play.langs.get(0)); } } /** * * @return the default locale if the Locale cannot be found otherwise the locale * associated to the current Lang. */ public static Locale getLocale() { String lang = get(); Locale locale = getLocale(lang); if (locale != null) { return locale; } return Locale.getDefault(); } public static Locale getLocale(String lang) { for (Locale locale : Locale.getAvailableLocales()) { if (locale.getLanguage().equals(lang)) { return locale; } } return null; } }
不难看出,Play在获取国际化设置的时候大概是这么处理的:
1.首先从 ThreadLocal 中获取,这个地方是由开发者在代码手动 set 的,也就是 Lang.set("zh")这样的。
2.如果 ThreadLocal 没有,则框架会自己去尝试解决,首先会从 Cookie 中获取,如果没有就从 HTTP 请求中获取 Header 的 accept-language 。如果还没有,那么就会去做一个默认的设置。默认的设置规则是:如果 application.conf 有定义的话,那么取第一个,如果没有,那么设置为空字符串“”。
以上的整个过程仅是我个人见解,欢迎指正:)
PS:eweb4j也马上要支持国际化啦。