質問: ``` public class Application extends Controller { public static play.mvc.Result index() { return ok(controllers.Assets.at("/public", "index.html", true)); } } ``` 上記のように`/public/index.html`をレスポンスとしたいのですが、`controllers.Assets.at`の戻り値は`play.api.mvc.Action`なので型不一致でコンパイルエラーとなります。 どうすればコントローラから公開アセットを返せるでしょうか?
回答: play 2.2.0ではありますが、以下のコードで実現できました(が非常に煩雑です)。 ``` public class Application extends Controller { public static Result index() throws Throwable { play.api.Application app = Play.application().getWrappedApplication(); scala.Option option = play.api.Play.resource("public/stylesheets/main.css", app); String content = org.apache.commons.io.IOUtils.toString(option.get()); return ok(content); } } ``` `controllers.Assets.at`の戻り値はActionであるため、コントローラ内で使用するにはあまり適切でなさそうです。ここでは`at`メソッドの中身を参考に実装しています。 Playのディレクトリ構成において`public/stylesheets/main.css`があると仮定します。 まずこのファイル自体を取得するために、`Play.resource()`メソッドを使います。 このメソッドは`Play.api.Applicationオブジェクト`が必要となります。しかし簡単に取得する方法が見つかりませんでした。そのため、`Play.Application`オブジェクトを取得してから`getWrappedApplication()`メソッドを呼び、`Play.api.Application`オブジェクトを取得しました。 `resource()`メソッドに使用するリソースのパスと`Play.api.Application`を渡すと、`scala.Option`オブジェクトが返ります。これはJava 8でのOptionと同じようなものと考えればよいです。ここでは該当ファイルが絶対にあるものと仮定しているので、`get`メソッドを呼んでURLオブジェクトを取得します。それをすべて文字列にするために`IOUtils.toString()`メソッドを使っています。 最後にこの文字列(ここではCSSファイルの内容)を`ok()`メソッドに渡せば、公開アセットにあるファイルの内容をレスポンスとして返すことができました。 私もあまりエレガントな方法とは思えないのですが、この方法しか見つからなかったため回答しました。 もしもっとよい方法をご存じの方がいれば、ぜひ回答を追加してください!