こんにちは。まっつんです。今回はApache Wicket(以下、Wicket)のウィザードを使用してユーザ登録アプリケーションを実装していきます。WicketはWebアプリケーションをステートフルに実装することができるフレームワークです。だからこそ、まっつんチャレンジシリーズで取り上げられているのですのが:-)
では、具体的にどのようにステートフルなWebアプリケーションを実装すればよいのでしょうか?
ステートフルなアプリケーションを実装する
実はWicketはデフォルトでステートフルに振る舞うので、開発者がステートフルにするために特別に行うことは何もありません。実装の中心となる Wizard クラスを継承した RegistrationWizard クラスを見てみましょう。
public class RegistrationWizard extends Wizard {
private static final long serialVersionUID = -8454579322127935177L;
private User user;
public RegistrationWizard(String id) {
super(id);
user = new User();
WizardModel model = new WizardModel();
model.add(new FormStep());
model.add(new ConfirmationStep());
model.setCancelVisible(false);
init(model);
}
@Override
public void onFinish() {
setResponsePage(FinishPage.class);
}
private abstract class RegistrationWizardStep extends WizardStep {
private static final long serialVersionUID = 1L;
@Override
public String getTitle() {
return "User Name";
}
}
private final class FormStep extends RegistrationWizardStep {
private static final long serialVersionUID = 1966418816672654290L;
public FormStep() {
Form<?> form = new Form<Object>("form");
RequiredTextField<String> firstNameText = new RequiredTextField<String>("firstName",
new PropertyModel<String>(user, "firstName")
);
firstNameText.add(new StringValidator.MaximumLengthValidator(255));
form.add(firstNameText);
RequiredTextField<String> lastNameText = new RequiredTextField<String>("lastName",
new PropertyModel<String>(user, "lastName")
);
lastNameText.add(new StringValidator.MaximumLengthValidator(255));
form.add(lastNameText);
add(form);
}
}
private class ConfirmationStep extends RegistrationWizardStep {
private static final long serialVersionUID = -2422494195732514895L;
public ConfirmationStep() {
add(new Label("firstName",
new PropertyModel<String>(user, "firstName"))
);
add(new Label("lastName",
new PropertyModel<String>(user, "lastName"))
);
}
}
}
今回実装したユーザ登録アプリケーションでは RegistrationWizard クラスはPiece_Unityのアクションクラスに相当します。RegistrationWizard クラスにserialVersionUIDが定義されていることから、おそらくWicketはこのクラスのインスタンスをステートフルの境界とした部分的な継続を実現しているのでしょう。
処理としてはモデルである User クラスをコンストラクタで1度だけインスタンス化し、各ページのコンストラクタでそのインスタンスとフォームコンポーネントを関連付けています。ご覧のとおり、セッションに関するコードは一切ありません。これがステートレスなフレームワークであれば、いたるところでセッション変数の保存と復元を行う必要があるところです。
たったこれだけのコードでフォームの設定、バリデーションなどユーザ登録アプリケーションで必要なほとんどすべての処理を行っています。Webアプリケーションをステートフルに実装すると可読性のよいすっきりとしたコードを書くことができます。
それでは実行してみましょう。問題なくユーザ登録アプリケーションが動作します。
同じフローを複数のウィンドウで動作させるとどうなるか?
ここでちょっとした実験を行ってみます。先ほどのURI http://localhost:8080/registration/?wicket:interface=:13:::: をコピーしてもうひとつウィンドウに貼り付けて別々に実行します。interface=:13 の部分がPiece_Unityのフロー実行チケット(フローのインスタンスを識別するための文字列)に相当すると思われるので、この部分が同じということは同じフローのインスタンスとして認識されるはずです。はたしてどうなるでしょうか?
実験の結果、ふたつのウィンドウは同期しました。つまり、ふたつのウィンドウは同じフローの状態を参照しているということになります。まぁ、チケットを含むURIが同じなわけですから、当たり前と言えば当たり前ですね。
おもしろいのは、今いるステートに対して予期しないイベントがリクエストされた場合、Wicketは例外を発生させるということです。
この動きは、現在のステートに予期しないイベントが発生した場合、そのまま現在のステートにとどまるPiece_Unityとは対象的です。例外が RuntimeException であることから推測すると、Wicketでは同じフロー(正確には同一のフローインスタンス)をマルチウィンドウで動かすことは想定外なのでしょう。
やはりステートフルは良い!
これまで取り上げてきたフレームワークでもそうでしたが、今回の RegistrationWizard クラスの実装もPiece_Unityのユーザ登録アプリケーションのアクションクラスRegistrationActionと似た構造になりました。WicketとPiece Frameworkはプログラミング言語の面でもJavaとPHPと比較的近いので他のフレームワークよりもさらに類似点が多いかもしれません。
それにしても、やはりステートフルは良いですね。今回も RegistrationWizardクラス が担当するべき処理に注力できているのはステートフルだからこそです。なのに、どうしてステートフルが流行らないんだろう?
トラックバック(0)
- このブログ記事のトラックバックURL:
