文档

§使用消息进行国际化

§指定您的应用程序支持的语言

您使用语言标签为应用程序指定语言,语言标签是专门格式化的字符串,用于标识特定语言。语言标签可以指定简单的语言,例如“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.frconf/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) 通过以下方式确定语言

  1. 查看 Request 是否通过检查其 transientLang() 方法设置了瞬态语言。
  2. 在请求中查找 PLAY_LANG cookie。
  3. 查看请求的 Accept-Language 标头。
  4. 使用应用程序的默认语言。

要将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()。有关更多详细信息,请参阅测试您的应用程序

下一步:依赖注入


发现文档中的错误?此页面的源代码可以在 这里 找到。阅读完 文档指南 后,请随时贡献拉取请求。有疑问或建议要分享?前往 我们的社区论坛 与社区展开讨论。