0

次のような状況があります: 提供された 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 コンテンツのみを提供します。

情報: Java で Play 2 を使用しています

よろしくお願いします

4

3 に答える 3

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) {
    ....
}

このアプローチはもう少し将来性がありますが、より多くのコードとクラスを含み、おそらく現在探しているものほど一般的ではありません.

于 2013-05-28T23:12:37.570 に答える
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;
    }
}
于 2013-05-29T15:07:43.120 に答える
0

リフレクションでこれを行う方法の例を次に示します。上記の方法は、テンプレートの数が不明な場合や、テンプレートを追加するたびにコードを更新したくない場合には実用的ではありません..

className は、レンダリングするテンプレートへの絶対パスです

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

return ok((Html) result);
于 2013-08-31T11:00:27.387 に答える