Java 如何在Play Framework 2.5模板中注入应用程序
在Play框架的新版本2.4/2.5中,他们进一步向注入所有内容和删除服务器状态迈进Java 如何在Play Framework 2.5模板中注入应用程序,java,templates,playframework,playframework-2.0,playframework-2.5,Java,Templates,Playframework,Playframework 2.0,Playframework 2.5,在Play框架的新版本2.4/2.5中,他们进一步向注入所有内容和删除服务器状态迈进play.play.application()现在不推荐使用。但是,我需要模板中的应用程序(例如,使用play.i18n.Lang.availables(play.play.application())在所有页面上显示所有受支持的语言) 我知道我可以: 将play.Application显式传递给我的所有模板 向我的模板添加一个隐式参数,如@()(隐式应用程序:play.Application)。但是,在我的J
play.play.application()
现在不推荐使用。但是,我需要模板中的应用程序(例如,使用play.i18n.Lang.availables(play.play.application())
在所有页面上显示所有受支持的语言)
我知道我可以:
- 将
显式传递给我的所有模板play.Application
- 向我的模板添加一个隐式参数,如
。但是,在我的Java项目中,它不是真正隐式的,每次渲染模板时我都必须传递它@()(隐式应用程序:play.Application)
- 。但是,这也需要弃用的
play.api.play.current
play.Application
----更新:----
迄今为止,我尝试了以下设置:
index.scala.html:
@(title: String)
@template(title) { //here is the play.Application obviously missing, however I don't want to pass it in every template - even worse in every Controller <-- this is the core of my question
Welcome to my page!
}
@(title: String)(content: Html)(implicit app: play.Application)
<html>
<head>
<title>@title</title>
</head>
<body>
<p>Is live? @app.isProd</p>
@content
</body>
</html>
public Result index() {
return ok(views.html.index.render("home"));
}
您可以使用Play.current()获取应用程序,或者在控制器中注入应用程序,如下所述。模板应获取play.Application类型的参数 应该是这样的 比如说,模板是injectappexample.scala.html:
@(app: play.Application)
.... use the app object
@this(configuration: play.api.Configuration)
@(key: String)
config = @configuration.get[Seq[String]](key).mkString(", ")
控制员:
public class SomeController extends Controller {
Provider<Application> applicationProvider;
@Inject
public SomeController(Provider<Application> applicationProvider) {
this.applicationProvider = applicationProvider;
}
public Result injectAppExample() {
return ok(injectappexample.render(applicationProvider.get());
}
}
public class SomeController extends Controller {
Configuration configuration;
@Inject
public SomeController(Configuration configuration) {
this.configuration = configuration;
}
public Result injectAppExample() {
return ok(injectappexample.render(configuration.getString("SOME_PROPERTY"));
}
}
控制员:
public class SomeController extends Controller {
Provider<Application> applicationProvider;
@Inject
public SomeController(Provider<Application> applicationProvider) {
this.applicationProvider = applicationProvider;
}
public Result injectAppExample() {
return ok(injectappexample.render(applicationProvider.get());
}
}
public class SomeController extends Controller {
Configuration configuration;
@Inject
public SomeController(Configuration configuration) {
this.configuration = configuration;
}
public Result injectAppExample() {
return ok(injectappexample.render(configuration.getString("SOME_PROPERTY"));
}
}
通常不鼓励注入应用程序本身,因为这会使您的代码非常难以测试。相反,想想你真正需要什么,然后直接注入
如果您在几乎每个模板中都需要很多东西,我的建议是创建某种上下文类,您可以将其注入控制器中,然后将其传递给模板。首先,尽管您正在询问如何注入应用程序,但您真正需要的是配置 你可以在游戏2.5中做类似的事情。我将展示构造函数注入,您可以根据需要使用字段注入
import com.google.inject.Inject;
import play.Configuration;
public class MyClass{
private Configuration conf;
@Inject
public MyClass(Configuration conf){
this.conf = conf;
}
}
现在您有了配置类。然后特别针对您在评论中发布的要求,您可以这样做
List<Object> langList = conf.getList("play.i18n.langs");
//conf.getList("") returns an object array.
//You can cast to Strings (assuming you are using Java8).
List<String> languages = new ArrayList<>(langList.size());
for (Object object : langList) {
languages.add(Objects.toString(object, null));
}
List langList=conf.getList(“play.i18n.langs”);
//conf.getList(“”)返回一个对象数组。
//您可以强制转换为字符串(假设您使用的是Java8)。
列表语言=新的ArrayList(langList.size());
用于(对象:langList){
add(Objects.toString(object,null));
}
现在您可以在
语言中查看您的语言列表了
,我只需要查看一下PlayFramework2.6.x。可以根据以下文档将对象注入模板:
我实现了一个简单的示例(有点做作),并使用了scala:
test.scala.html:
@(app: play.Application)
.... use the app object
@this(configuration: play.api.Configuration)
@(key: String)
config = @configuration.get[Seq[String]](key).mkString(", ")
家庭控制器.scala
package controllers
import javax.inject._
import play.api._
import play.api.i18n._
import play.api.mvc._
/**
* This controller creates an `Action` to handle HTTP requests to the
* application's home page.
*/
@Singleton
class HomeController @Inject()(cc: ControllerComponents, testView: views.html.test) (implicit configuration: Configuration) extends AbstractController(cc) with I18nSupport{
def test() = Action { implicit request =>
Ok(testView("play.i18n.langs"))
}
}
路线:
GET /test controllers.HomeController.test()
配置对象被注入views.html.test模板,视图本身被注入控制器。注意模板中的@this(配置:play.api.configuration)
语句。Play将在模板后面生成一个类,该类带有注入配置对象的构造函数
请注意,注入控制器的配置在此特定代码中没有任何角色。在我找到这个解决方案之前,我尝试了其他排列。。。假设您有一个由控制器调用的外部模板使用的内部模板,并且内部模板需要配置对象,您需要从控制器自上而下地提供配置,并在层次结构路径中的所有模板中,将隐式配置:play.api.configuration
参数添加到需要该参数的模板,如下所示:@(消息:字符串)(隐式消息提供者:消息提供者,配置:play.api.configuration)
。然后,控制器注入的配置会一直传送到最上面的模板,直到需要它的模板。谢谢您的回答,但是Play.current()
在Play 2.5中也被弃用,我希望将其注入模板而不是控制器中(如何注入控制器在这里很清楚,并且有很好的文档记录)你到底需要用play.Application做什么?我想列出所有可用的语言,比如newplay.api.i18n.DefaultLangs(play.play.Application().configuration()).availables()
,以显示语言切换器。我已经按照你的要求给出了答案。如果你对此有任何问题,一定要告诉我。:)不幸的是,没有。我仍然在寻找一种方法,将一些东西注入到我的模板中。到目前为止,所有答案都需要我将其传递给所有模板。play.Application只是一个例子,我也不知道如何注入play.Configuration之类的东西。因此,基本上您正在努力注入正确的东西??感谢您的回答,您能否进一步解释如何“直接注入”?我根本不知道如何在模板中注入任何内容,而不必每次在Java代码中呈现模板时都传递它。不,这就是我的意思——每次使用模板时,仍然需要将该上下文对象显式传递到模板中。