Play framework: HelloWorldを書いてみた
今日はPlay frameworkを使ってHelloWorldを書いてみたいと思います。そのため、まずは前回作ったtestAppの構造を理解してから作業に入っていきます。下に書くのはtestAppの中身です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
treeApp ├── README ├── app │ ├── controllers │ │ └── Application.java │ └── views │ ├── index.scala.html │ └── main.scala.html ├── conf │ ├── application.conf │ └── routes ├── project │ ├── Build.scala │ ├── build.properties │ └── plugins.sbt ├── public │ ├── images │ │ └── favicon.png │ ├── javascripts │ │ └── jquery-1.9.0.min.js │ └── stylesheets │ └── main.css └── test ├── ApplicationTest.java └── IntegrationTest.java |
コンパイル前のワークスペースの中は大きく分けて、「app」「conf」「project」「public」「test」という5つディレクトリに分かれています。そしてコンパイルを行うとこれらに追加して「target」というディレクトリが追加されます。それでは各フォルダについて説明してきます。
app
アプリケーション本体が格納されるディレクトリです。Play frameworkは他のフレームワークと同様、MVCモデルを採用しているので作成直後では「views」と「controllers」しかありません。デフォルトの設定では、モデルの格納場所として「models」というディレクトリをサポートしているので必要な場合は作成追加して利用します。
conf
Play frameworkの設定をファイルなどを格納するディレクトリです。ファイルにはroutesファイルというパスとコントローラを結びつけるファイルや、application.confというPlay framework自体の設定するファイルなどを配置します。
project
SBTというビルドシステムの設定ファイル群が格納されています。基本的にここを触ることはあまりないと思います。
public
スタイルシートや、javascript、画像ファイルなどを格納するためのディレクトリです。デフォルトで設定されているので、設定を変えずに使うならこのフォルダにリソース類を格納して使いましょう。
test
テストコードを格納する場所です。ここに格納されたテストコードを利用してPlayの試験を行います。
target
コンパイルした状態のものを格納するファイルです。ここにクラスファイルなどページを構成する要素が格納され参照されます。
とまぁ、ざっくりここまで説明しました。今回、HelloWorldを書くにあたって必要になってくるのは、
- app配下のファイル
- conf配下のファイル
の二つになります。
それでは早速作ってみましょう。
まず、「app」配下の「views」に「helloworld.scala.html」と「header.scala.html」というファイルを作成します。eclipseの新規作成でPlayのテンプレートを作成することが出来ます。まぁ、作成されるファイルの中身には2行程度しか記述がないので、自分で作成して書いてもほぼ変わらないと思います。ファイルを作成したら、以下のように記述していきます。
helloworld.scala.html
1 2 3 4 5 6 7 8 |
@(mainString:String) <!DOCTYPE html> <html lang="ja"> @header(mainString) <body> <h1>@mainString</h1> </body> </html> |
header.scala.html
1 2 3 4 5 |
@(titleString:String) <head> <meta charset="UTF-8"> <title>@titleString</title> </head> |
以上の記述が出来たら、「controllers」配下に「HelloWorld.java」というクラスを作成します。
こちらはクラスの作成から生成することをオススメします。コンストラクタは必要ありません。
HelloWorld.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
package controllers import play.* import play.mvc.* import view.html /** * Hello World 表示用コントローラクラス */ public class HelloWorld extends Controller { /** * Hello World 表示処理 */ public static Result index(){ return ok(helloworld.render("Hello World!"); } } |
次に「conf」ディレクトリにある「routes」ファイルを編集します。
1 2 3 |
GET / controllers.Application.index() ↓ <span style="color: #ff0000;">GET / controllers.HelloWorld.index()</span> |
これで完成です。
プロジェクトのフォルダに移動して以下のコマンドを打ちます。
1 |
> play run |
それでは「http://localhost:9000」にアクセスしてみましょう。以下のように表示されたら成功です。
では解説を。
まず、viewですが「helloworld.scala.html」と「header.scala.html」で「@」という文字の後に色々見慣れない記述が目立ちます。これはHTMLにScalaという関数型言語を書き込んでいます。要は「@」以降がプログラミング言語になっているわけです。Scalaは「JAVA」や「C」と違って文末に「;」を付与しなくても改行していればプログラムを認識してくれます。なので基本は文末の「;」は付けず、同一行へ複数の処理を記述する時だけ記述します。まずはその前提条件を踏まえつつ見ていきます。
1行目の処理です。
1 2 3 4 5 6 7 |
<strong>helloworld.scala.html</strong> @(mainStirng:Stirng) <strong>header.scala.html</strong> @(titleStirng:Stirng) |
これはJavaやCで言うところのメソッドや関数の引数宣言を表しています。一番分かりやすい例で言うと「helloworld.scala.html」内で「@header(mainString)」という記述がありますが、これが呼び出しです。引数に指定した「mainString」が「header.scala.html」の「titleString」に格納されます。呼び出された「header.scala.html」は値を出力した後のhtmlを返します。「mainString」は「controller」の「HelloWorld.java」から呼ばれた際に格納されます。
値の出力は以下の記述で出来ます。
1 2 3 4 5 6 7 |
<strong>helloworld.scala.html</strong> <h1>@mainStirng</h1> <strong>header.scala.html</strong> <title>@titleStirng</title> |
以上、view側となりますが、仕組みが分かれば結構簡単に書けます。。。仕組みを理解するまでが大変ですが。
まぁ、一つ言うとすればScalaが分かりづらいですね。JavaやCと色々違うので違和感があります。
さて、それではcontrollerを見ていきましょう。
先ほど記述した「HelloWorld.java」を見ていきます。まず「import」部分です。
1 2 3 |
import play.* import play.mvc.* import view.html |
結構見慣れないライブラリです。もうお分かりでしょうが、これはPlay frameworkで用意されているライブラリです。おおむねWebアプリを作るうえで必要そうなものはラップして用意されています。
次にクラスの宣言です。
1 |
public class HelloWorld extends Controller { |
上の記述で「Controller」クラスを継承しています。これを行うのがミソです。これを行わないと、後で記述する「ok」メソッドが認識されません。
さて、ようやっと実際の処理を行っているコントローラのメソッドにたどり着きました。
1 2 3 |
public static Result index(){ return ok(helloworld.render("Hello World!"); } |
さて説明をしていきます。このメソッドはResult型を返す静的メソッドです。return部分に「ok」というメソッドがありますが、これがブラウザに200OKを返します。引数にはResults型(先ほどのメソッドの宣言の型はResult型なので若干違います)のメソッドとして「render」メソッドが記述されています。これはscala.htmlファイルの呼び出しを行い、そこの引数に値をセットしてhtmlを生成するメソッドです。これにより生成されたhtmlをレスポンスとしてokが返します。
以上で大体の説明は終わりです。
最後にroutesファイルについて説明します。
先ほどまで説明したファイルを配置しただけではPlayに認識してもらえません。Playに認識してもらうにはroutesファイルを編集し、URLを入力された際にどのコントローラメソッドが呼び出されるのか宣言を行い結びつける必要があります。
1 |
GET / controllers.HelloWorld.index() |
この記述を行うことで「http://localhost:9000/」にアクセスしたときに「HelloWorld.java」の「index()」メソッドを呼び出すようになります。routesファイルにはGETの他にPOSTも記述することが出来ます。用途に応じて使い分けるといいかもしれません。
最後に一連の呼び出しの流れを書いていこうと思います。
- http://localhost:9000/にリクエストが送られてくる
- Play frameworkがroutesファイルを参照して「controllers.HelloWorld.index()」を呼び出す
- HelloWorld.javaがhelloworld.scala.htmlに「Hello World!」という文字列を渡してhtmlを生成する
- HelloWorld.javaが生成したhtmlをレスポンスとしてブラウザに送信する
- ブラウザに生成されたhtmlが表示される
以上となります。かなり長くなってしまいましたが、なんとなく理解はできたと思います。これからもっと高度な使い方をすると説明も難しくなるんだろうな。。。ということで今日はここまで。