![Lv.2 Playフレームワークのルート処理って大切。 [play framework2.0][java]](https://soylatte.jp/wp-content/themes/soy-magazine/assets/images/no-thumbnail.png)
レベル2は、conf/routesファイルの説明です。
これはどのURLを叩くと、どのクラスのどのメソッドが呼ばれるか、を定義する
ファイルです。
strutsとかspringとかseasar2とか他のフレームワークでもお馴染みの機構です。
ただこれらと違い、記述方法がXMLじゃないので、多少慣れが必要になります。
でも簡単です。
1:静的なURLの設定
記述方法を記します。
GET /clients controllers.Clients.list()
[/java]
こういう形になっていて、構造的には、
動詞 | URL | Actionメソッドのフルパス | |
GET | /clients | controllers.Clients.list() |
と、これが基本です。
これを和訳(?)すると、
「GETで/clientsが叩かれたらcontrollers.Clientsクラスのlist()を実行します」
という感じ。
慣れたら簡単ですよね。
2:動的なURLの設定
上述は静的なURLの定義でして、動的な定義もできます。
┗2-1:URLを動的にする基本
こんな感じです。
GET /clients/:id controllers.Clients.show(id)
[/java]
/:idが加わりました。
動的なURLはすべて「/」から始まります。
正規表現だと[^/]+という状態です。
これを和訳すると
「GETで/clients/123が呼ばれたらcontrollers.Clientsクラスのshow(id)を実行します」
これでOKです。
┗2-2:URLの詳しい定義
OKですが、このままだと/clients/abcと叩かれた場合でもcontrollers.Clients.show(id)
が実行されます。
それが仕様なら問題ありません。
しかし、/clients/123と/clients/abcでは振る舞いが異なる仕様の場合は、以下の
ように正規表現を利用して定義します。
GET /clients/$id<[0-9]+> controllers.Clients.show(id)
[/java]
これで、idが数字の場合のみcontrollers.Clients.show(id)が呼ばれます。
ホッ…
┗2-3:引数の詳しい定義
っとしたのもタバノマ(=ツカノマ=束の間)です。
もしあなたのプロジェクトで、controllers.Clients.クラスに
show(String id)とshow(Long id)という2つのアクションが記述してある場合、
このままだと予期せぬ動作をしてしまいます。
っというのも、play!ではcontrollers.Clients.show(id)という記述は、
デフォルトでString idと解釈されるからです。
/clients/$id<[0-9]+>と定義しているからといって、数字つながりでLong idの方を
実行してはくれません。
でも大丈夫です。
「引数:型」と指定してあげれば、ちゃんとshow(Long id)を実行してくれます。
GET /clients/$id<[0-9]+> controllers.Clients.show(id:Long)
[/java]
このように、
- URL側を正規表現で定義する
- アクションの引数は型も定義する
というのが一番カッチリした記述方法になります。
┗2-4:重複したメソッドの定義
上述のURL正規表現+アクション引数の型指定を使って、conf/routes上でオーバーライドの
ような振る舞いをすることができるでしょうか。
GET /clients/$id<[0-9]+> controllers.Clients.show(id:Long)
GET /clients/$id<[a-z]+> controllers.Clients.show(id:String)
[/java]
残念ながら(?)これはコンパイルエラーが発生します。
3:その他の記述方法
上述が基本形として、他にも下記のような定義があります。
┗3-1:クエリを引数にする
// http://example.com/?page=index
GET / controllers.Application.show(page)
[/java]
この場合はURLの定義に工夫はなく、単に
- conf/routesで定義したアクションの引数名:show(page)
- Javaクラスの引数名:show(String page)
- クエリのkey:/?page=123
の3者が同名であれば良い。
┗3-2:デフォルト引数も定義できる。「?= 1」
GET /clients controllers.Clients.list(page: Integer ?= 1)
[/java]
ページングなどの処理などに使うとか。
┗3-3:複数のクエリを定義したい。「/.*」
//http://example.com//files/images/logo.png
GET /files/*name controllers.Application.download(name)
[/java]
もし分かっているなら/files/imagesまでは静的に定義しておいた方がいいかも。
imagesだけじゃなくて、pdfとかもくるかもしれないなら、このくらい曖昧でも
OKかと。
4:競合する定義があった場合
ちなみに、もし競合する定義がファイル内にあったら、一番上のものが優先される。
GET /:test controllers.Application.test(test)
GET /hello controllers.Application.sayHello()
[/java]
この状態で、http://localhost:9000/helloとアクセスすると、
controllers.Application.test(test)が実行されます。
定義が増えてきたら分かりづらいですね、、、。
いっそエラー出してほしい気もします。