§使用消息进行国际化
§指定您的应用程序支持的语言
您使用语言标签为应用程序指定语言,语言标签是专门格式化的字符串,用于标识特定语言。语言标签可以指定简单的语言,例如“en”表示英语,语言的特定区域方言(例如“en-AU”表示澳大利亚使用的英语),语言和脚本(例如“az-Latn”表示用拉丁字母书写的阿塞拜疆语),或者这些的组合(例如“zh-cmn-Hans-CN”表示中国使用的简体汉字的汉语普通话)。
要开始,您需要在 conf/application.conf
文件中指定应用程序支持的语言
play.i18n.langs = [ "en", "en-US", "fr" ]
这些语言标签将用于创建 play.i18n.Lang
实例。要访问应用程序支持的语言,您可以将 play.i18n.Langs
组件注入到您的类中
import play.i18n.Langs;
import play.i18n.Messages;
import play.i18n.MessagesApi;
import javax.inject.Inject;
import java.util.Collection;
import java.util.Collections;
import java.util.Locale;
public class MyService {
private final Langs langs;
@Inject
public MyService(Langs langs) {
this.langs = langs;
}
}
可以使用 lang.toLocale()
方法将单个 play.i18n.Lang
转换为 java.util.Locale
对象
java.util.Locale locale = lang.toLocale();
§外部化消息
您可以在 conf/messages.xxx
文件中外部化消息。
默认的 conf/messages
文件匹配所有语言。您可以指定其他语言消息文件,例如 conf/messages.fr
或 conf/messages.en-US
。
消息可通过 MessagesApi
实例获得,该实例可以通过注入添加。然后,您可以使用 play.i18n.Messages
对象检索消息
class SomeService {
private final play.i18n.MessagesApi messagesApi;
@Inject
SomeService(MessagesApi messagesApi) {
this.messagesApi = messagesApi;
}
public void message() {
Collection<Lang> candidates = Collections.singletonList(new Lang(Locale.US));
Messages messages = messagesApi.preferred(candidates);
String message = messages.at("home.title");
}
}
如果您不想使用 preferred(...)
来检索 Messages
对象,您可以通过显式指定消息的语言直接获取消息字符串
String title = messagesApi.get(Lang.forCode("fr"), "hello");
请注意,您应该使用 依赖注入 注入 play.i18n.MessagesApi
类。例如,使用 Guice,您将执行以下操作
public class MyClass {
private final play.i18n.MessagesApi messagesApi;
@Inject
public MyClass(MessagesApi messagesApi) {
this.messagesApi = messagesApi;
}
}
§在控制器中使用
如果您在控制器中,您可以通过当前的 Http.Request
获取 Messages
实例
public Result index(Http.Request request) {
Messages messages = this.messagesApi.preferred(request);
String hello = messages.at("hello");
return ok(hellotemplate.render(messages));
}
MessagesApi.preferred(request)
通过以下方式确定语言
- 查看
Request
是否通过检查其transientLang()
方法设置了瞬态语言。 - 在请求中查找
PLAY_LANG
cookie。 - 查看请求的
Accept-Language
标头。 - 使用应用程序的默认语言。
要将Messages
用作表单处理的一部分,请参阅处理表单提交。
§在模板中使用
获得 Messages 对象后,您可以将其传递到模板中
@(messages: play.i18n.Messages)
@messages.at("hello")
还有一种更短的等效形式,即messages.at
,许多人发现它很有用。
@(messages: play.i18n.Messages)
@messages("hello")
使用messages.at(...)
或简单地使用messages(...)
的本地化模板像正常一样调用
public Result index(Http.Request request) {
Messages messages = this.messagesApi.preferred(request);
return ok(hellotemplate.render(messages));
}
§更改语言
如果要更改当前请求的语言(但不是针对未来的请求),请使用Request.withTransientLang(lang)
,它设置当前请求的瞬态语言。
如上面所述,在调用MessagesApi.preferred(request)
时,将考虑请求的瞬态语言。这对于更改模板的语言很有用。
public Result index(Http.Request request) {
Lang lang = Lang.forCode("en-US");
Messages messages = this.messagesApi.preferred(request.withTransientLang(lang));
return ok(hellotemplate.render(messages));
}
如果要永久更改语言,可以通过在Result
上调用withLang
来实现。这将为未来的请求设置PLAY_LANG
cookie,因此在后续请求中调用MessagesApi.preferred(request)
时将使用它(如上面所示)。
public Result index(Http.Request request) {
Lang lang = Lang.forCode("fr");
Messages messages = this.messagesApi.preferred(request.withTransientLang(lang));
return ok(hellotemplate.render(messages)).withLang(lang, messagesApi);
}
§格式化消息
消息使用java.text.MessageFormat
库进行格式化。例如,如果您定义了以下消息
files.summary=The disk {1} contains {0} file(s).
然后,您可以指定参数为
Messages.get("files.summary", d.files.length, d.name)
§关于撇号的说明
由于 Messages 使用java.text.MessageFormat
,请注意单引号用作转义参数替换的元字符。
例如,如果您定义了以下消息
info.error=You aren''t logged in!
example.formatting=When using MessageFormat, '''{0}''' is replaced with the first parameter.
您应该期望以下结果
String errorMessage = messages.at("info.error");
Boolean areEqual = errorMessage.equals("You aren't logged in!");
String errorMessage = messages.at("example.formatting");
Boolean areEqual =
errorMessage.equals(
"When using MessageFormat, '{0}' is replaced with the first parameter.");
§从 HTTP 请求中检索支持的语言
您可以检索特定 HTTP 请求支持的语言
public Result index(Http.Request request) {
List<Lang> langs = request.acceptLanguages();
String codes = langs.stream().map(Lang::code).collect(joining(","));
return ok(codes);
}
§使用显式 MessagesApi
MessagesApi
的默认实现由DefaultMessagesApi
实例支持,该实例是 Scala API。但是,您可以实例化DefaultMessagesApi
并将其手动注入到MessagesApi
中,例如
private MessagesApi explicitMessagesApi() {
return new play.i18n.MessagesApi(
new play.api.i18n.DefaultMessagesApi(
Collections.singletonMap(
Lang.defaultLang().code(), Collections.singletonMap("foo", "bar")),
new play.api.i18n.DefaultLangs().asJava()));
}
如果您需要MessagesApi
实例进行单元测试,您还可以使用play.test.Helpers.stubMessagesApi()
。有关更多详细信息,请参阅测试您的应用程序。
下一步:依赖注入
发现文档中的错误?此页面的源代码可以在 这里 找到。阅读完 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?前往 我们的社区论坛 与社区展开讨论。