根据URL参数渲染模板

时间:2013-05-28 20:11:22

标签: playframework-2.0 playframework-2.1

我有以下情况:我需要根据提供的URL参数呈现模板。例如:

http://localhost:9000/abc -> renders abc.scala.html
http://localhost:9000/def -> renders def.scala.html

最简单的解决方案是在路径文件中定义这些要求:

GET /abc     controllers.Application.abc()
GET /def     controllers.Application.def()
...

然后在应用程序控制器中:

public static Result abc() {
    return ok(abc.render());
}

但我正在寻找更“通用”的解决方案。像这样:

GET /:myparameter     controllers.Application.test(myparameter: String)

不幸的是我不知道如何在我的控制器中“调用”相应的视图。我正在考虑某种地图,其中每个参数都映射到视图但没有成功。我试过这样的

Map<String, play.api.templates.Html>

当然,这只能为我提供HTML内容,而不是我想要呈现的“模板”。

信息:我正在使用Play 2 with Java

祝你好运

3 个答案:

答案 0 :(得分:1)

我实际上认为您建议自己维护参数值映射到Html类型的提案是可行的选择:

public class Application extends Controller {

    private static final Map<String, Html> views = new HashMap<>();

    static {
        views.put("abc", abc.render());
        views.put("def", def.render());
        ...
    }

    public static Result test(final String myparameter) {

        final Html view = views.get(myparameter);
        if (view != null) {
            return ok(view);
        } else {
            // Unsupported parameter
            return badRequest();
        }
    }
}

在上面的代码中,所有模板都在静态块中预渲染。根据您描述问题的方式判断,您的模板似乎没有任何参数,因此这种早期渲染模板的方法应该适合您。

但是,您可能会/将拥有接收参数且无法提前呈现的模板。在这种情况下,您可以采用的另一种方法是使用操作组合的解决方案:

/*
 * This action is composed of many different actions that form a 
 * chain of responsibility.
 */
@Abc
@Def
...
public static Result test(final String myparameter) {
    ....
}

这种方法更具有前瞻性,但涉及更多代码和类,可能不像您目前所寻求的那样通用。

答案 1 :(得分:0)

如果您使用的是Java 1.7,则可以使用简单的开关

public static Result test(final String myparameter) {

    switch(myparameter){
        case "abc":
          //Initialize x,y
          abc.render(x,y);
          break;
        case "def":
          //Initialize x,y,z
          defview.render(x,y,z);
          break;
    }
}

答案 2 :(得分:0)

以下是如何使用反射执行此操作的示例。如果您拥有未知数量的模板和/或每次添加模板时都不想更新代码,则上述方法不实用。

className是您要呈现的模板的绝对路径

Class<?> clazz = Class.forName(className);
Method renderMethod = clazz.getMethod("render");
Object result = renderMethod.invoke(null);

return ok((Html) result);