この記事は以下の記事の続きです。
ScalaでPlayFramework: 環境構築編
Playは公式ドキュメントがちゃんとあるので、細かいところはそちらを参照してください。
Play 2.5.10 documentation
この記事を執筆している段階では、日本語化されているのは2.4までみたいなので、頑張って英語読みましょう。
全てが全て変わっているというわけでもないので、基本2.4を見つつ、うまく行かなかったら2.5見てみるでもいいかもしれません。
この記事の内容は、だいたい以下のページに書かれています。
ルーティングを見てみる
プロジェクトルート以下のconf/routes
を開きます。初期状態では以下のようになっているはずです。
...
# An example controller showing a sample home page
GET / controllers.HomeController.index
# An example controller showing how to use dependency injection
GET /count controllers.CountController.count
# An example controller showing how to write asynchronous code
GET /message controllers.AsyncController.message
...
method /path action
と書くことで、/path
にmethod
でアクセスが来たときaction
が実行されるようになります。
下でコントローラにアクションを書いていきますが、アクションができたら都度このファイルに追加していきます。
コントローラをいじる
プロジェクトルート以下のapp/controller/HomeController.scala
を開きます。最初はアクションが一つだけあります。
...
@Singleton
class HomeController @Inject() extends Controller {
...
def index = Action {
Ok(views.html.index("Your new application is ready."))
}
}
アクションを作るには、ズバリAction
を定義してやればいいです。
文字列を返す
とりあえずHello Worldしてみましょう。
app/controller/HomeController.scala
に以下を追加します。
...
def hello = Action {
Ok("World")
}
...
ルーティングにも追加します。
...
GET /hello controllers.HomeController.hello
...
できたら、プロジェクトを起動してブラウザからアクセスしてみましょう。
http://localhost:9000/hello
World
という文字列が表示されればOKです。
ちなみに、run
でプロジェクトを起動すれば、ファイルを更新した時にいちいちプロジェクトを再起動する必要はありません。
ファイルに更新があった場合は、アクセス時にコンパイルが走ります。その為、更新した直後1回目のアクセスは少し時間がかかります。
もし、ファイルを更新後アクセスすると反応がなくなってしまう場合は、以下の設定を追加するとうまくいくようになるかもしれません。
...
fork in run := false
パラメータを受け取る
アクションに引数をつけることでパラメータを受け取れるようになります。
...
def show(id: String) = Action {
Ok(id)
}
...
URLのパスの一部を受け取る
/
から次の/
までのパスを受け取る場合は:id
を使います(idは任意の文字列)。
パスは特に指定しない限り、String
で受け取ることになります。
...
GET /show/:id/go controllers.HomeController.show(id)
...
例えば、/show/1/go
とか/show/hello/go
とかがマッチします。その時id
となるのは、1
とhello
です。
ある/
以降の全てのパスを受け取る場合は*path
を使います(pathは任意の文字列)。
...
GET /show/*path controllers.HomeController.show(path)
...
/show/hoge/fuga
の場合、path
はhoge/fuga
になります。
正規表現を使いたい場合は、$id<regex>
を使います(idは任意の文字列、regexは正規表現)。
...
GET /regex/$id<[0-9]+> controllers.HomeController.show(id)
...
/regex/1
とか/regex/9999
とかがマッチします。
ちなみに、conf/routes
は上から順番にマッチするかの判定が行われます。
例えば下記のように書いてしまうと、controllers.SomeController.hello
は絶対に呼ばれません。注意しましょう。
GET /show/:id controllers.SomeController.show(id)
GET /show/hello controllers.SomeController.hello
逆にこれを利用し、一番最後にどんなパスにもマッチする様書いておけば、自作の404ページを表示させたりすることもできます。
...
# 最後
GET /*any controllers.SomeController.response404(any)
GET(POST)パラメータを受け取る
例えば以下のようなアクションを定義します。
...
def params(a: String, b: Int, c: Option[String]) = Action {
Ok("%s, %d, %s".format(a, b, c))
}
...
ルーティングには以下のように書きます。
...
GET /params controllers.HomeController.params(a, b: Int, c: Option[String])
...
これだけです。/params?a=hoge&b=1&c=fuga
みたいな感じでアクセスすれば、パラメータが渡せていることが確認できます。
パラメータでString
以外のものを扱う場合は、型を明記する必要があります。
型をOption
にすることで、あっても無くてもいいパラメータを作ることができます。
パラメータにデフォルト値をもたせたい場合は以下のようにします。
...
GET /params_b_default controllers.HomeController.params(a, b: Int = 1, c: Option[String])
...
/params_b_default?a=hoge
みたいな感じでアクセスできます。もちろんb
やc
に値を指定しても構いません。
リダイレクトする
一行でできます。
...
def redirectHello = Action {
Redirect("/hello")
}
...
レスポンスヘッダをいじる、セッションを使う、JSONで返す
3つまとめて。後ろにくっつけます。
...
def additional = Action {
Ok("additional")
.withHeaders(
CACHE_CONTROL -> "max-age=3600",
ETAG -> "xx"
)
.withSession(
"connected" -> "hoge",
"foo" -> "bar"
)
.as(JSON)
}
...
セッションのチェックは以下の感じで。connected
はただのキーなので、お好きな名前で大丈夫です。
...
def checkSession = Action { request =>
request.session.get("connected").map { user =>
Ok("Hello " + user)
}.getOrElse {
Unauthorized("you are not connected")
}
}
...
セッションをクリアするにはこうします。
...
def clearSession = Action { request =>
Ok("cleared")
.withNewSession
}
...
Flashとやらを使う
Flashは1度の遷移のみ有効なセッション、みたいなものらしいです。
def redirectOnly = Action { implicit request =>
Ok {
request.flash.get("success").getOrElse("Welcome!")
}
}
def success = Action {
Redirect("/redirect_only")
.flashing(
"success" -> "yeah!!"
)
}
おわりに
公式ドキュメントがよくできています。もうそっち読めばいいんじゃないかな。
自分なりにまとめるっていうのも必要ですよね。うん、きっとそうに違いない。
次はビューを扱います。