如何在控制器外注入 MessagesApi?

How to inject MessagesApi outside a controller?

我有一个简单的 class 服务,它被完美地注入到我的应用程序中。但是,我试图注入 messages api 来读取我的消息文件中的一些键,但我遇到了同样的错误:

1) Could not find a suitable constructor in play.i18n.Messages. Classes must have either one (and only one) constructor annotated with @Inject or a zero-argument constructor that is not private. at play.i18n.Messages.class(Messages.java:61)

public class SampleServiceImpl implements SampleService {
  private MessagesApi messages;

  @Inject
  public SampleServiceImpl(MessagesApi messages){
     this.messages = messages;
  }
}

@ImplementedBy(SampleServiceImpl.class)
    public interface SampleService {
}

有没有办法通过 DI 做到这一点?

编辑:

我可以通过这样做获得价值,但它看起来并不优雅,有什么选择吗?

messages.get(new Lang(new Locale("en")), "ticket.form.title")

这样"non-elegancy"的原因是语言(和Messages)取决于请求。

默认行为是消息根据 cookie、可用语言和默认语言检测当前语言。

引擎盖下的一些软件:Messages messages = messagesApi.preferred(request());

  • Will select a language from the request, based on the languages available, and fallback to the default language if none of the candidates are available.

幸运的是,there is a special method 您可以使用您想要的语言来初始化 Messages

import play.i18n.MessagesApi;
import play.i18n.Messages;
import play.i18n.Lang;

import java.util.Arrays;
import java.util.List;
import java.util.Locale;

...

Locale englishLocale = new Locale("en");
Lang englishLang = new Lang(englishLocale);
List<Lang> prefferedLangs = Arrays.asList(englishLang);

Messages messagesCustom = messagesApi.preferred(prefferedLangs);

// the time for elegancy 
messages.at("ticket.form.title");

我建议你创建微型 MessagesApiCustom 服务,它将在初始化时执行这几行代码,然后将 at 方法代理到 messages.at,所以它看起来像:

public class SampleServiceImpl implements SampleService {
  private MessagesApiCustom messages;

  @Inject
  public SampleServiceImpl(MessagesApiCustom messages){
     this.messages = messages;
  }

  private void doSomeStuff(){
    Strign message = messages.at("message.key")
  }
}

你可以更进一步,实现基于注解的语言选择:

 @Named("FR")
 private MessagesApiCustom messages;

当然,如果您需要动态选择语言,那么就使用Play中已有的方法即可。