如何在 Play Framework 2.6 应用程序中通过依赖注入使用消息?
How to use Messages via Dependency Injection in a Play Framework 2.6 app?
我正在将 Play 网络应用程序迁移到 v2.6,考虑到消息依赖于请求的 HTTP 上下文,我无法理解依赖项注入如何与消息一起工作。
我像这样向控制器添加了场注入:
public class MyController extends Controller {
@Inject
private Messages m;
public Result all(String uuid){
// using m.at("xxxxxx")
}
}
我有这样的东西:
play.api.UnexpectedException: Unexpected exception[ProvisionException:
Unable to provision, see the following errors:
1) No implementation for play.i18n.Messages was bound.
while locating play.i18n.Messages
for field at
controllers.MyController.m(MyController.java:23)
while locating controllers.MyController
for the 5th parameter of router.Routes.<init>(Routes.scala:63)
然后我尝试通过在应用程序文件夹中添加一个模块 class 来配置 Messages 接口的实现来修复它:
import com.google.inject.AbstractModule;
import play.i18n.Messages;
import play.libs.akka.AkkaGuiceSupport;
import play.mvc.Http;
public class Module extends AbstractModule implements AkkaGuiceSupport {
@Override
public void configure() {
bind(Messages.class).toInstance(Http.Context.current().messages());
}
}
这给了我另一个错误:
1) No implementation for play.i18n.Messages was bound.
at Module.configure(Module.java:10) (via modules:
com.google.inject.util.Modules$OverrideModule -> Module)
2) An exception was caught and reported. Message: There is no HTTP
Context available from here.
at com.google.inject.util.Modules$OverrideModule.configure(Modules.java:177)
我看过 code example of how DI works with Play,但我认为这已经在 Play for Messages 中实现了。
我开始认为我应该在每个控制器中使用 Http.Context.current().messages() 然后通过构造函数将它传递给任何其他 class,这很冗长,也许它首先违背了 DI 的目的。
您需要在构造函数中初始化它并按如下方式使用它
public class MyController extends Controller {
private final play.i18n.MessagesApi messagesApi;
@Inject
public MyController (MessagesApi messagesApi) {
this.messagesApi = messagesApi;
}
public Result all(String uuid){
messagesApi.get(Lang.forCode("en"), "hello");
}
}
或者,如果使用 Scala,请在您的控制器中添加 I18nSupport 并确保您的操作添加 implicit request =>
以使用默认语言丰富请求:
import play.api.i18n._
@Singleton
class HomeController @Inject()(cc: ControllerComponents)
extends AbstractController(cc) with I18nSupport {
def index() = Action { implicit request =>
Ok(views.html.index())
}
}
在您的主模板和特定模板中确保导入 MessagesProvider:
@()(implicit messagesProvider: play.api.i18n.MessagesProvider)
然后在模板中的任意位置添加如下国际化消息:
<h1>@messagesProvider.messages("app.title")</h1>
我正在将 Play 网络应用程序迁移到 v2.6,考虑到消息依赖于请求的 HTTP 上下文,我无法理解依赖项注入如何与消息一起工作。
我像这样向控制器添加了场注入:
public class MyController extends Controller {
@Inject
private Messages m;
public Result all(String uuid){
// using m.at("xxxxxx")
}
}
我有这样的东西:
play.api.UnexpectedException: Unexpected exception[ProvisionException:
Unable to provision, see the following errors:
1) No implementation for play.i18n.Messages was bound.
while locating play.i18n.Messages
for field at
controllers.MyController.m(MyController.java:23)
while locating controllers.MyController
for the 5th parameter of router.Routes.<init>(Routes.scala:63)
然后我尝试通过在应用程序文件夹中添加一个模块 class 来配置 Messages 接口的实现来修复它:
import com.google.inject.AbstractModule;
import play.i18n.Messages;
import play.libs.akka.AkkaGuiceSupport;
import play.mvc.Http;
public class Module extends AbstractModule implements AkkaGuiceSupport {
@Override
public void configure() {
bind(Messages.class).toInstance(Http.Context.current().messages());
}
}
这给了我另一个错误:
1) No implementation for play.i18n.Messages was bound.
at Module.configure(Module.java:10) (via modules:
com.google.inject.util.Modules$OverrideModule -> Module)
2) An exception was caught and reported. Message: There is no HTTP
Context available from here.
at com.google.inject.util.Modules$OverrideModule.configure(Modules.java:177)
我看过 code example of how DI works with Play,但我认为这已经在 Play for Messages 中实现了。
我开始认为我应该在每个控制器中使用 Http.Context.current().messages() 然后通过构造函数将它传递给任何其他 class,这很冗长,也许它首先违背了 DI 的目的。
您需要在构造函数中初始化它并按如下方式使用它
public class MyController extends Controller { private final play.i18n.MessagesApi messagesApi; @Inject public MyController (MessagesApi messagesApi) { this.messagesApi = messagesApi; } public Result all(String uuid){ messagesApi.get(Lang.forCode("en"), "hello"); } }
或者,如果使用 Scala,请在您的控制器中添加 I18nSupport 并确保您的操作添加 implicit request =>
以使用默认语言丰富请求:
import play.api.i18n._
@Singleton
class HomeController @Inject()(cc: ControllerComponents)
extends AbstractController(cc) with I18nSupport {
def index() = Action { implicit request =>
Ok(views.html.index())
}
}
在您的主模板和特定模板中确保导入 MessagesProvider:
@()(implicit messagesProvider: play.api.i18n.MessagesProvider)
然后在模板中的任意位置添加如下国际化消息:
<h1>@messagesProvider.messages("app.title")</h1>