Play Framework 2.0 Session?いえいえ Cookie でしょ

Play Framework 2.0 で、ページを戻った時に、以前の選択した内容を再現したいなーというお話。
となると、値はどこかに保存しておかなきゃいけないわけで。
Session? いえいえ、ステートレスな Play ! だからこそ、Session の概念はポイしなきゃ。
値の保存は Cookie に頼りましょ。

Java であれこれ作ってきて、サーブレット + jsp に慣れ親しんだ身としては、
情報の保持を考えるときに、ついつい Session に頼りがちです。
でも、ステートレスを特徴とする Play Framework には Session は似合いません。
ステートレスってなあに?という人にはこことかが分かりやすいです。
クラウドベース、複数サーバー、非同期通信で随時接続、サーバーからの情報の頻繁なプッシュ‥‥
これらを考慮したうえで軽量なサーバー環境を実現するのはステートレスでないと割が合わないのです。
(参照:こことか

それでも、「単に軽量なフレームワークとして Play! を選んだだけ!」
「だから Session を使いたい!」という方もいるはず。

Play! にも Session と呼ばれるものは存在します。
(参照:Play! Japan Doc. 2.0.4 セッションとフラッシュスコープ
ただし、このセッション機能は以下のような注意点があります。
「Cookie を利用してる」「サーバーにデータは残らない」
「上限は 4KB」「格納できるのは String のみ」
ここで Session と呼ばれているものは、実際には Cookie だということ。

「これじゃダメ! Servlet の HttpSession がどうしても使いたいんだ!」という方には、
プラグインやライブラリを導入することをお勧めしておきます。
(参照:Play2 で HttpSession を使う

せっかくなのでここからは、ビュー側で jQuery を使って cookie を扱う方法をまとめときましょう。
jQuery で cookie を扱う時には jQuery のプラグイン jquery-cookie を使うととっても便利。

github などからダウンロードしたら、ビューのあたまでインポートしておくことを忘れずに。

cookie への値のセットと、セットした値の参照、値のクリアはこんな感じ。

セットした値をクリアしたいときは null をセットします。
こうしておけば、ブラウザを閉じるまでは null 値が cookie に残っちゃいますが、
ブラウザを閉じると、キーのセットごとクリアしてくれます。

また、cookie の対象とするパスや有効期限( expires )を手書きで設定することもできます。
こんな感じ。

こんな風に、第3引数に配列で指定します。
特定の時分秒に expires させたいときなども、Date 関数で日付を作ってしまえば簡単。

ちなみに、第3引数が設定されていない場合は、
path はそのスクリプトが動作したパスが、expires は -1 が、それぞれセットされます。

最後は、ビューで受け取った値を cookie にセットする方法と、
値の存在チェックをして、実際に値を使う時の例をまとめておきましょう。
Play! の機能としての Session は特に使わず、ベタベタな方法で cookie を利用しています。

値をセットするビューの頭で、Scala のメソッドを定義します。
ビューで受け取った値を cookie にそのまま放り込んじゃう感じ。

先ほど Scala で定義したメソッドを javascript 側で使います。
わざわざ Scala のメソッドを使う意味はあまりないかもですけど、
条件分岐なんかがある場合はこの方法が便利なはず。

そして、cookie に保存した値を別のビューの javascript で、
値の存在をチェックしたうえで使います。

こんな感じ。
ここでは、連結された cookie を分割して配列に保存しています。

好みの問題になりますが、cookie に複数の値を保存するときは、
たくさんのキーに散らばった状態で保存するよりも、
ここで上げたように、文字列を連結して保存したほうが、管理が楽な気がします。
もちろん、連結文字を扱わないように気を付けてあげる必要が出てきちゃいますが‥‥。

というわけで、今日は Play! で Session と cookie について考えたというお話でした。

Play Framework 2.0 で Eclipse を使ってデバッグする

方法を知ったのがわりと後になってからだったので、早く知っとけばよかったなーという意味も込めて、
ちゃんとマニュアル読めば書いてあるはなしかもですけど、
Eclipse でのデバッグの方法をまとめておきますね。

1. Play! 起動時にデバッグコマンドで起動する

Windows で Play! サーバーを起動する場合、
次のようなコマンドを記載したバッチファイルを作っておけば便利です。

1行目の set _JAVA_OPTIONS=”-Dfile.encoding=SJIS” は、
Play! のエラーがコマンドプロンプトに表示されるときの文字化けを防いでくれます。
Java からのアウトプットが UTF-8 なので、何も設定しないと文字化けしちゃうんですよね。
かといって、次のようにコマンドプロンプト自体を UTF-8 にして

処理しようとすると、動作がとっても重くなって使い物にならないわけで。
コマンドプロンプトは cp932 のまま、Java 側のアウトプットを SJIS にするのが正解です。
なぜ cp932 でなくて SJIS か‥‥? この辺、追いかけ始めると結構面白そうですが‥‥。
とりあえず今のところ、うちの手元では SJIS で元気に動いてるから良しとしましょうか。

3行目では play debug run という風に、debug キーワードを追加して run しています。
実行するとプロンプトには以下のように表示されます

注目するのは

の1行です。

9999 番ポートでデバッグ用の dt_socket をリッスンしていますよーというメッセージ。
この 9999 番ポートを Eclipse のリモートデバッグで接続先として指定すると、
Eclipse のデバッグで socket を横取りしてデバッグできるという仕組み。
詳しい解説はここらへんかしら?

Play! 側で用意するのはこれだけです。

2. Eclipse 側でデバッグの設定

次は Eclipse 側です。
具体的には、Eclipse 上でこんな風に設定します。
まず、「実行」→「デバッグの構成」を開きます。
左ペインの「リモート Java アプリケーション」を右クリックし「新規」を選択。
play-debug-eclipse
こんな風に、接続プロパティーに「ホスト:localhost」「ポート:9999」を設定します。
設定ができたら右下「デバッグ」ボタンをクリック。

3. あとはいつものようにブレークポイントを設定して

4. Play! アプリを動作させるだけ

指定したブレークポイントでちゃんと停止して、デバッグパースペクティブを開けますし、
ステップ実行もできちゃいます。

デバッグを中止するときは、デバッグパースペクティブのデバッグビュー上の「切断」をクリック。
また、再度デバッグを行いたいときは、Eclipse の実行メニューの「ヒストリーのデバッグ」に、
さっき実行したデバッグの設定が残っています。

Play! アプリの開発も、デバッグさえできればこっちのものですよね!

Play Framework 2.0 ‥‥絶望的?複数チェックボックスの値を送信する

最初に。余裕のある人は、Play Framework 2.1 を使うことをおすすめしますよ~‥‥

ということで、Java + Play! 2.0 で、複数チェックボックスの値を送信する方法です。
調べた限りでは、どうやら Java + Play! 2.0 の環境では、
multiple checkbox の binding 処理にバグがあるみたい‥‥。
(参考:こことか。)
もちろん、select ボックスの複数選択も同じくできないようですね。

で、この内容、Play! 2.1 では修正されているみたいなんです。(参考:こことか。)
なので、それでもあえて Java + Play! 2.0 で複数チェックボックスを扱わなきゃいけない!
という人以外には、下記の方法はおすすめしないかもしれません。

さて、では本題です。
バグがある。正攻法じゃダメ。じゃあどうするか‥‥ javascript に頼るしかないですねえ。
値を区切り文字を挟んで連結して、hidden 項目に入れて送信しちゃいましょう。
やや面倒ですが、ほかに思いつく楽な方法がありませんから‥‥しょうがないです。

手順はこんな感じ。
1. フォームの submit イベントを拾う。
2. チェックボックスの値を区切り文字を挟みながら連結する。
3. 連結した値は hidden 項目に格納。
4. フォームを送信。
5. 受け取った内容を区切り文字で分割。

ソースを見ていきましょう。
まず html から

チェックボックスは submit 時に値を付ける必要がありませんので、name を宣言していません。

javascirpt はこんな感じです。

今回はカンマ区切りで連結してみました。
hidden フォームに格納してしまえば、あとは普通のフォームの値と同様に扱えます。

半分以上がおまけの機能=全てチェックするためのボタンのための処理です。
「全てチェック」は、よくチェックボックスで機能を用意してある場合がありますが、
動作の整合性を取るための機能の実装に混乱をきたしがちです。
だったらいっそのことボタンにしちゃったほうが楽でしょ?

次にコントローラー側では、受け取ったフォームの値を区切り文字で分割してあげないといけません。

受け取った値は、ここには書いていない TestFormData クラスで受け取ることとします。
また、DB から取得した内容は、これまたここには書いていない PREF_TBL クラスで受け取ることとします。
java.util.regex.Pattern.split で分割した値を java.util.Arrays.asList で配列に保存しています。
あとは org.apache.commons.lang3.StringUtils.join で
区切り文字を入れながら再度連結なんてこともしています。

routes については書いてませんが、一般的な Form の POST 処理で OK ですので、
悩ましいところはないはずです。

いかがでしたでしょうか。
複数チェックボックスの値を扱えない‥‥というところがコマッタさんでしたが、
javascript を使えば難なくクリアできちゃいますよというお話でした。

Play Framework 2.0 ビューで西暦を和暦に変換する

Java で Play Framework 2.0 に取っ組んでるわけですけど、
ビューの上であれこれ処理をしなきゃいけなくなると、どうしても Scala からは逃れられなくなっちゃいます。

たとえば、同じ画面の上で西暦も和暦も表示したいぞ!なんてとき。
あらかじめコントローラーで両方を計算しておいて、ビューの引数を増やせば済むよね!
という力技ももちろんあるにはあるけれど、せっかくの Play! 2.0 なんだから Scala 使わなきゃ。

ということで、ビューの上で Scala で処理しちゃいましょう、というのが今回のお話です。
Scala 初心者なので、スマートさにはずいぶん欠けるかもしれません。
でも、Scala をかじるきっかけにはなるでしょうし、
「あ、こんな感じね」というヒントにはなるかなーと考えてます。
そのうち、もうちょっとブラッシュアップできてくといいかなー。

ひとまずソースです。

ビューの一番アタマの部分です。
ページの引数として、pages.TestPageData クラスのオブジェクトを受け取ってます。
デフォルトでは pages なんていうパッケージはありませんが、
ページで扱うデータは pages パッケージのクラスに、フォームで扱うデータは forms パッケージのクラスに
それぞれ格納するのがうちの癖です。
やっぱり直観的にわかるのが一番いいですしね。

次がビューでの Scala のメソッドの宣言方法です。

こんな風に書きます。
@getWareki がメソッド、(in: String) で String 引数型の引数を in という変数名で扱います。
ちなみに、一般的な Scala プログラムで同じ内容を記述すると

となります。

Scala は Java ベースの言語で、Java のライブラリをそのまま扱えるという特性を持っています。
ここでも java.util.Date をそのまま使ってしまいます。
また、文末に「 ; 」セミコロンがありませんけれど、誤植じゃありません。
Scala は明示的にセミコロンを書かなくても、適切に処理してくれます。

変数の定義をします。定義の方法には val と var の2種類があります。
val は定義すると値を変更することはできません。Java の static のように使うことができます。
var は一般的な変数です。
型の宣言がありませんが、Scala ではこれは普通のことです。
Scala のコンパイラには強力な型推測機能があります。
明示的に型が推論できる場合には省略してしまうことができます。

入力値を trim して、Integer で受け取っているだけの処理です。
try ~ catch 文は Java でも見なれたものです。
ただし、Exception を case 文で受け取るところが違います。
もう一つ見なれない => はパターンマッチした時を示します。
まさに矢印そのものと捉えていいと思います。

では、Scala の StringLike.format メソッドを使って、現在日付から、年の部分のみを抽出しています。
StringLike.format については、ここらへんを参考にするとよいかもです。

西暦を和暦(平成)に変換するために1988を引いています。
年号が変わったら‥‥その時はその時で!
Some(…) は、Scala の Option というラップクラスの子クラスです。
Option クラスは、値が Null のときでも NullPointerException を返さないという特徴があります。
値があるときは、Some(…) の中身を、処理に失敗した時は None オブジェクトを返してくれます。

戻り値を明示していませんが、これも Scala の特徴です。
最後の行で処理した結果を、自動的に戻り値として返してくれます。
今回の場合は Some(wareki.toString()) の結果を返します。

もし、結果がマイナスになっちゃった!という人は、入力値を疑ってくださいね。
もともとの年度が Javascript で生成したものであるなら、
ブラウザによっては 1900 年からの差分を返す場合があります。
javascript 側でこんな風に記述しておくとよいかもです。

実際の表示部分ではこんな風に使います。

というわけで、今回は Scala を少しかじってみました。
コントローラーで処理するか、ビューで処理するかは好みの分かれるところだと思いますが、
ビューで処理する方法も覚えておくと、柔軟に対応できていいんじゃないかなーと思ってます。

Scala について、もう少し深く触れておきたいなー、という場合は、
この2冊がおすすめです。

「Scala プログラミング入門」は、これまで Java で書いてきたけど、
Scala もかじってみたいという人に最適。
「Scala スケーラブルプログラミング」は通称「コップ本」と呼ばれているバイブル的な存在です。
2冊まとめてもとめておくと、今後も活用できるはずです。

Play Framework 2.0 で jQuery の ajax メソッドを使って非同期通信

Play 2.1 + Scala だと、非同期通信に関する強化やアップデートがいろいろあるようだけど‥‥
参考:こことか
でも、Play 2.0 + Java でも非同期通信したいっ!というのが今回のハナシ。

非同期通信を使って、何をどんなふうに実現したいかというところをまずまとめておきます。
うーんと、こんなふうかな。
1) ビュー上で、ユーザーが画面フォーム上の Select 要素の選択肢を変更
2) jQuery.ajax メソッドを使って、Select 要素の選択肢を非同期で送信
3) コントローラーでは、非同期で受信した内容を条件に、DBから関連データを抽出
4) 抽出したデータを JSON 形式に変換して、ビューへ返す
5) ビュー上で、受け取った JSON 形式のデータをもとに、新たな Select 要素を生成する

非同期通信を使わなくても実現可能な内容ではあるけれど、
いまどき非同期のほうがスマートかな?というのが個人的な印象です。

これらの内容、いろいろ冗長かもですが、せっかくなので細かくまとめておくことにします。

さて、じゃあまず 1) の画面フォームの準備から。
いつものようにフォームヘルパーなどの機能は使わずに書いてます。

よくある感じにまとめてみました。
都道府県を選んだら、選んだ内容に合わせて市区町村の選択肢を切り替える、
ということをやってみたいと。

次は 2) jQuery.ajax メソッドを使って非同期通信を行う部分です。
都道府県が変更されたときに、非同期通信を行うように jQuery で記述します。

こんな感じです。
都道府県の change イベントに処理をバインドします。
type は post 、url には routes の定義を記載します。
データには、都道府県の選択肢をバインドします。
select ボックスで選択した内容は、$(‘#pref_list option:selected’).val() という風に取得できます。
ここでのポイントは cache を false としておくことです。
ブラウザやユーザーの環境によっては、戻り値の json データがキャッシュされてしまうのを防ぐためです。

success 時の処理は 5) 受け取った JSON 形式のデータをもとに、新たな Select 要素を生成する処理です。
select ボックスへの option の追加処理は、
以前の記事のようにie6対応の書き方にしています。
ie6を意識しないのであれば、もっとスマートに書けるんですけどね。

続いて、3) コントローラーで受信した内容を条件に、DBから関連データを抽出します。
ビューからの非同期 Request をコントローラーのアクションにバインドするために、
routes には次の定義を行っています。

コントローラーの Test クラスの changePref メソッドをコールします。
changePref メソッドはこんな感じ。

ちょっと冗長かも・・・。
フォームの値をフォーム用のクラスにバインドしています。
このあたりはなくてもいいんじゃない?という意見もあるかもですね。
取得したフォームの値をもとに、DBから値を取得します。
T02_PREF_LOCAL は、DBのテーブル用のクラスです。
フォームの値のための FormPref 、DBのテーブルのための T02_PREF_LOCAL はそれぞれこんな感じ。

DBにはクラスの定義と同じ名称・形のテーブルを準備しておきます。

続いて、4) 抽出したデータを JSON 形式に変換して、ビューへ返します。

Play! では、Scala に JSON 用のライブラリが用意されています。
これらのライブラリ、Java からも利用はできるようなのですが、
今回はいろいろの事情であえて jsonic を使うことにしました。
(検証用の時間が足りなかったりっだとか‥‥いろいろです)
JSON へのエンコードだけだと、上記のように非常に簡単な記述で済みます。
JSON への変換が済んだ文字列をそのまま戻り値とします。

戻り値を受け取ったあとの 5) の処理は 1) の箇所に記載済みです。

受け取った戻り値 data を $.parseJSON() でパースします。
パースした値は、$.each(value, function(id){…}) で、データごとの値を取得します。
パースしたデータの値は、テーブル用のクラスの変数名をキーにして格納されていますので、
市区町村名は childList[idx].local といった感じで取得できます。

こんな感じで、非同期通信でのやり取りが書けちゃいます。
Java で割と簡単に書けちゃうというところがポイントでしょうか。

Play Framework 2.0 で送信したフォームの中身をコントローラー上で HttpRequest レベルで確認する

今回は、Play Framework 2.0.4 で、ビューで送信したフォームの中身を
コントローラー側で生のまま確認したいなーということで、その方法を探ってみました。

Play! には、便利なフォームテンプレートやヘルパーの機能がいろいろあるらしいですけど、
まずはベーシックに使ってみましょうということで、私自身は今のところ使用してません。

今利用しているのは単純な Form で Submit された内容を
コントローラーで Form クラスに bindFromRequest で格納する方法です。
こんな感じ。

[ ビュー : Form(Values) ] → [ コントローラー : Form(Values) → UserForm(Values) ]

UserForm クラスは受け取ったフォームの値を格納するクラスです。
あらかじめ、こんな風に作ってあります。

ビューで送信したフォームの内容は、コントローラー上でこんな風に書けば簡単に取得できます。

@Required アノテーションのおかげで、year や month に値が入っていないと
エラーとしてはじいてくれます。

さて、この手順で作ってった場合、
ビューで送信したフォームの内容を生のままで確認したいときなどは、ちょっと困ってしまいます。
bindFromRequest メソッドで form に値を格納した段階で、中で処理されちゃっているからです。
本当に form の値がコントローラーに渡っているのかどうか疑わしいときなどです。

そんな時は、デバッグ中にでもこの値をチェックしましょう

currentに入っているのは現在のHttp通信のContextの中身そのもの。
HttpRequestの中身、つまりリクエストの内容がほしい場合は、

に入ってます。

HttpRequestのヘッダなども取得できるので、送信元IPなんかも取れちゃいますねー。
いろんな処理に応用できそうです。

Thunderbird の設定を便利にカスタマイズ

メーラーにはもう何年も Thunderbird を使っています。
Thunderbird の普及率は結構高いんじゃないかなー?
周囲を見る限りですけど、そんな風に感じています。

じゃあ、カスタマイズして便利に使ってます?
どんなのが便利でしょう?
そこにちょっと焦点を当ててみようかなというのが今回の記事です。

今日は、私自身が感じたこんな項目について。
「メールの量が増えてきて、毎日やってられなくて」
「受信したメールをいちいち既読にするのが面倒くさい!」
「自分の送ったメールがいつも行方不明、メールの文脈がさっぱりわからなくなる!」

では、ひとつ目の悩み、「メールの量が増えてきて、毎日やってられない」について。
受信メールにフィルターの設定をして、フォルダで振り分けるようにするのは、
ごく普通に設定されていることでしょう。
フィルターの設定は面倒ですけど、一度設定してしまえばあとはずっと自動的に処理されます。

必要な時に読み返すだけでいいメーリングリストなどは、フィルターで「既読」にしちゃえば、
受信したメールにいちいち手を煩わされることもないのでラクチンです。
WS000002

それからふたつ目は、ありがちな「受信したメールをいちいち既読にするのが面倒くさい!」というもの。

WS000003
オプションの詳細設定で「メッセージを○秒間以上表示していたら既読にする」設定もできますけど、
こんな風に設定すると「あとで処理したいから未読のままで残しておきたい」メールが出てきたときに、
勝手に既読にされちゃって、すごく不便な思いをすることになります。

そんなときに覚えたいのが、キーボードのショートカット。
Thunderbird のリファレンスにはたくさんのショートカットが掲載されていますが、自分の必要なものだけを覚えちゃえばラクチンです。
たとえば、「メインウィンドウ – メッセージ操作 – マーク」に掲載されている
「未読・既読の切り替え」=「M」
「すべてを既読にする」=「Shift + C」
これだけ覚えてしまえばいいんじゃないでしょうか?
自動で既読にする設定をオフにしてしまって、メッセージを既読にしたいときは「M」、
フォルダごと既読にするときは「Shift+C」で、まとめて処理できちゃいます。

最後にみっつ目。
「自分の送ったメールがいつも行方不明、メールの文脈がさっぱりわからなくなる!」というもの。
特に、送信と返信のやりとりが繰り返されたときや、返信を待たずに何度も送信をした時など、
自分がいったい何を送信したかわからなくなってしまうことがありますよね‥‥。
相手の返信に引用された自分の文章も、場合によっては部分が切り取られたり削除されたり。
かといって、その都度送信済みトレイを見に行っても、ツリー上に並んでいないので、
送信日時だけを頼りにメールを探し回らないといけません。
それを避けるために「メールを送るときは必ず自分をBCCに入れている」なんて人もいるかもしれません。
でも、それって「送信済みトレイ」の中身と「BCCした自分あてのメール」でダブっちゃいません?

そこでお勧めしたいのが「返信元のメッセージと同じフォルダに保存する」設定。
「ツール」の「アカウント設定」の「送信控えと特別なフォルダ」にあります。

WS000001
これをチェックしておけば、あとで返信元のフォルダでメールをツリー表示したときにも、
綺麗にツリーが並んで、前後関係がよくわかります。

そんなわけで、今日は Thunderbird の便利な設定について、3つお届けしました。
これであなたもメールの片づけ上手ですね♪

ie8やie9で動的に生成した項目の表示スタイルが乱れる

CSSにバグはない、javascriptも問題ない、なのになぜ?ieだから?

jQueryを使ってselectボックスの中身を動的に生成するようなケースで、ie8やie9で見てみると、
selectボックスの横幅がぐーんと伸びたのに、selectボックスを含むエレメントの横幅が伸びなくって、
ボックスが横へはみ出してしまうように見えちゃったというお話です。

文字だけだと説明がまどろっこしいですね‥‥。

今回はこのあたりを参考にボックス追加の処理を書いてます~。
引用すると、こんな感じ。

ええ、いまだにie6対応求められてるんですっ!
オキャクサマ都合とはいえ、システム屋さんの悲しい現実ですよねえ。

‥‥それはさておき
この時にieの「ズーム」機能を使ってズームを変更すると、
変更した時だけ正常に描画される!という現象が見られます。
でもその状態でまた動的に表示を変更すると、ズレが再発‥‥。

他のブラウザだと正常に表示されるので、CSSやjavascriptの問題ではないはず。
でもie8とie9だけはselectボックスとほかの要素が重なったり表示が乱れたり、
とにかくちゃんと画面が表示されません。ieのバグなわけ?

実はこの現象、ieの「互換表示設定」が原因です。
未確認ですが、ie10でも発生するかもしれません。
解消するには、「ツール」>「互換表示設定」で互換表示設定パネルを開きましょう。

ie9_gokan

ie9_gokan2
ここの「互換表示ですべてのWebサイトを表示する」をオフにします。

‥‥え、そこが最初からオフになってる場合はどうするんだって?
そうですね‥‥「互換表示ですべてのWebサイトを表示する」は、意図しない限りデフォルトではオフです。

では、今見ているページはローカルネットワークに作成したサイトではありませんか?
つまり「localhost」や「192.168.1….」なんて、IPアドレス直打ちでページを表示していませんか?
ポイントはイントラネット向けの設定がインターネット向けの設定とは別になっているところ。
「互換表示でイントラネットサイトを表示する」もオフにしましょう。

これで解決しました?

互換表示については普段意識しないだけでなく、
ローカルネットワークのページを表示している場合は、互換表示ボタンは表示されないんです。
そんなわけで、意外と気づきにくい落とし穴なのでしたー。

Play Framework 2.0 で Windows サーバー上に本番環境を構築する

Play Framework は手元で簡単に開発環境が構築できるのが魅力です。
自分ひとりであれこれ実験するにはうってつけ。
じゃあ、本番環境を構築するにはどうすればいいのか?それもWindowsサーバーに・・・
この情報が意外と少なかったので、まとめてみました。

ちょっとメモとして書いとくと、Play Framework を利用するにあたっては、
環境や言語などに依存して、ある程度自由度が異なってきます。
Linux > Windows ですし、2.0以降では Scala > Java で自由度が違います。
あえてWindows + Javaを選択してるうちってば・・・

今回参考にした情報はここらへんです。
参考記事では Windows 7 で動作したことを確認されているようですが、
同様の手法で Windows XP、Windows Server 2008 R2 でも動作することを確認しています。

簡単にまとめると、「Distributionパッケージ」を作成し、「NettyServerをYAJSWラッパー」を用いて
サービスとして常駐しちゃうよ、という方法です。
以下、手順としてまとめてみますね。

1. アプリケーションのアプリ名とアプリバージョンを修正しておきましょう
project/Build.scala にある appName と appVersion をそれぞれお好みのものに変更します

2. コマンドプロンプトで 作成した Play! アプリのフォルダへ移動し、以下のコマンドを実行します

play dist

3. Play! アプリのフォルダ内に「dist」フォルダが作成され、以下のファイル名でDistributionパッケージが出来上がります

[appName]-[appVersion]-yyyyMMdd.zip

4. 出来上がったzipを展開します。Windowsのバージョンによっては展開時にフォルダが2重になるので注意が必要です。

5. [appName]-[appVersion]-yyyyMMdd フォルダ内に「start」というファイルがあるはずです。
これは Linux 向けのシェルファイルなので、Windows 用のバッチファイルを同じフォルダに作成します。
以下の1行を記述し、「start.bat」と名前を付けます。

java %1 -cp “./lib/*;” play.core.server.NettyServer .

最後のピリオドも必要です。
また、アプリをデフォルトの9000番ではなく特定ポートを指定して起動したいなーという場合は、以下のようにします。

java %1 -Dhttp.port=80 -cp “./lib/*;” play.core.server.NettyServer .

6. 5.で作成したバッチファイルを実行します。
起動すると、コンソールにサーバーのPIDが表示されるので、これを覚えておきます。

7. YAJSW をダウンロードして、わかりやすい場所に展開しておきます。

8. コマンドプロンプトを開き、7.で展開したYAJSWの中のbatフォルダに移動して、次のコマンドを実行します。

genConfig.bat [6.で起動したPID]

9. サービスラッパーが自動的に構成され、保存されます。サービス名はNettyServerになっていますので、
アプリ名に書き換えたいときは YAJSW/conf/wrapper.conf 内の以下の設定を書き換えます。

wrapper.ntservice.name=アプリ名
wrapper.ntservice.displayname=アプリ名

10. コンソール上でサービスを動作させる場合は yajsw\bat の runConsole.bat を起動します。
起動したサービスを停止させたい場合は、開いているコンソール上で「Ctrl+C」を入力します。

11. 誤って10.のコンソールをそのまま閉じてしまった場合や、開いたままシステムをシャットダウンしてしまった場合、
次回起動時にNettyServerが正常起動しません。
この時は、アプリケーションのフォルダ([appName]-[appVersion]-yyyyMMdd フォルダ)内にある
「RUNNING_PID」というファイルを削除すると、正常に起動することができるようになります。

12. アプリの起動をWindowsのサービスに登録することもできます。
サービスに登録するときは「installService.bat」、サービスの起動は「startService.bat」、
サービスの停止は「stopService.bat」、サービスから削除するときは「uninstallService.bat」を
それぞれ使用します。
サービス名は9.で設定した内容で登録されます。

Windows では、「play start」コマンドも正常に動作しないという話ですし、
いろいろを考慮すると、これが一番安定した本番環境構築の方法なんじゃないかなーと思います。

Play Framework 2.0 + Java + Ebean でストアドプロシージャをコールする

Ebean はモデル一体型のORMフレームワーク。
DBの型をクラスに落としこんでなんぼの仕組みです。

ORマッパーってなんじゃらほい?というところはまだ理解できてませんけどね。
ここはそのうち追々‥‥

Ebean を使ってると、クラスとDBをマッチングさせるだけで、
SQLを書く必要もほとんどなくなっちゃいます。便利です。
Play Framework と Ebean についての解説は@ITのこの記事が分かりよいです。

でも、時には直接SQLを発行してみたいときもありますよね。
ストアドプロシージャをコールしたいな~と思ったりだとか。
そういう時は、Ebeanのexecuteメソッドを使います

static int Ebean.execute(CallableSql callableSql)

CallableSqlはプリペアドステートメントを提供するインタフェースです。

実際の簡単な使い方はこんな感じ。

簡単。
SqlQueryインタフェースと違って、パラメータに名前ラベルを使えないっぽいところが玉に瑕?

さっそく実行すると・・・あれ?プロシージャ実行されない。
executeメソッドの戻り値には “-1” が返ってきます。
“-1” ってなんだっけ・・・うーん?
探っていると、execute(SqlUpdate sqlUpdate)メソッドに記述がありました。

Returns:
the number of rows updated or deleted. -1 if executed in batch.

なんだ、じゃあちゃんと実行されてるんじゃない。
じゃなんでDB側に反映されてないんだろ?

イロイロ調べるうちに、上の書き方が悪いのかプロシージャの書き方が悪いのか、
executeをコールするだけだと、プロシージャの処理が完了していないっぽい様子。
うーん‥‥どうすりゃいいっていうんよ。

詳細わかんないですが、ここらへんを参考に、
トランザクションで括って、commitを多めに発行してみましたー。どうかな?

実行実行‥‥動いたー!
最後2度commitしてることになりますけど、これでちゃんと動いてくれたからまあいっか。

ちなみに、今回のお相手のDBはSqlServer2008Expressです。
なので、プロシージャの呼び出しもSQLServer風味。

Oracleだと “{ call StoredProcedure_1(?,?) }” みたいになるんでしょうか?
Oracle詳しくないからなー。
ブラケットは自動的にBEGINとCOMMITに置き換えられるそうな。
でも、ブラケットとの間にスペースを空けないと、ちゃんと動かないよー!
みたいな議論がここらへんにあったので一応メモっておきましょうか‥‥