Lv.2 Playフレームワークのルート処理って大切。 [play framework2.0][java]

Lv.2 Playフレームワークのルート処理って大切。 [play framework2.0][java]

レベル2は、conf/routesファイルの説明です。
これはどのURLを叩くと、どのクラスのどのメソッドが呼ばれるか、を定義する
ファイルです。
strutsとかspringとかseasar2とか他のフレームワークでもお馴染みの機構です。

ただこれらと違い、記述方法がXMLじゃないので、多少慣れが必要になります。

でも簡単です。

1:静的なURLの設定

記述方法を記します。

[java toolbar=”false”]
GET /clients controllers.Clients.list()
[/java]

こういう形になっていて、構造的には、

動詞 URL Actionメソッドのフルパス
GET /clients controllers.Clients.list()

と、これが基本です。

動詞部分には、GET, POST, PUT, DELETE, HEADが適用できるようです。

これを和訳(?)すると、
GET/clientsが叩かれたらcontrollers.Clientsクラスのlist()を実行します」
という感じ。

慣れたら簡単ですよね。

2:動的なURLの設定

上述は静的なURLの定義でして、動的な定義もできます。

┗2-1:URLを動的にする基本

こんな感じです。

[java toolbar=”false”]
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では振る舞いが異なる仕様の場合は、以下の
ように正規表現を利用して定義します。

[java toolbar=”false”]
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)を実行してくれます。

ちなみにジェネリクスの場合は、List[String]と記述する模様。
[java toolbar=”false”]
GET /clients/$id<[0-9]+> controllers.Clients.show(id:Long)
[/java]

このように、

  • URL側を正規表現で定義する
  • アクションの引数は型も定義する

というのが一番カッチリした記述方法になります。

┗2-4:重複したメソッドの定義

上述のURL正規表現+アクション引数の型指定を使って、conf/routes上でオーバーライドの
ような振る舞いをすることができるでしょうか。

[java toolbar=”false”]
GET /clients/$id<[0-9]+> controllers.Clients.show(id:Long)
GET /clients/$id<[a-z]+> controllers.Clients.show(id:String)
[/java]

残念ながら(?)これはコンパイルエラーが発生します。

3:その他の記述方法

上述が基本形として、他にも下記のような定義があります。

┗3-1:クエリを引数にする

[java toolbar=”false”]
// 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」

[java toolbar=”false”]
GET /clients controllers.Clients.list(page: Integer ?= 1)
[/java]

ページングなどの処理などに使うとか。

┗3-3:複数のクエリを定義したい。「/.*」

[java toolbar=”false”]
//http://example.com//files/images/logo.png
GET /files/*name controllers.Application.download(name)
[/java]

もし分かっているなら/files/imagesまでは静的に定義しておいた方がいいかも。
imagesだけじゃなくて、pdfとかもくるかもしれないなら、このくらい曖昧でも
OKかと。

4:競合する定義があった場合

ちなみに、もし競合する定義がファイル内にあったら、一番上のものが優先される。

[java toolbar=”false”]
GET /:test controllers.Application.test(test)
GET /hello controllers.Application.sayHello()
[/java]

この状態で、http://localhost:9000/helloとアクセスすると、
controllers.Application.test(test)が実行されます。
定義が増えてきたら分かりづらいですね、、、。
いっそエラー出してほしい気もします。

‘ class=’movie_thumb’ align=”left”/>

‘ rel=’vidbox 800 600′ title=’play framework(playフレームワーク)2.0を使ってみた動画’ class=’filter_img’>