オレオレJava Webフレームワークを作ってみる。その1
以前から、Webフレームワークを妄想していたのですが、S2Utilが便利そうということでなんとなく作っています。
新しい発想はなく、色々、既存のフレームワークをパクってる感じです。。
以前の記事「いろんなJava Webフレームワークで同じ画面を作ってみる(Index) - よしなしごと」のようにサンプルを記載します。簡単な足し算画面です。とりあえずこのサンプルコードが動くレベルまではできてます。。
まずは、Actionクラスから
package webapp.action; import org.selva2.webframework.ActionResult; import org.selva2.webframework.RequestParams; import org.selva2.webframework.annotation.Default; import org.selva2.webframework.annotation.Event; import org.selva2.webframework.annotation.IntegerType; import org.selva2.webframework.annotation.Label; import org.selva2.webframework.annotation.RequestScope; import org.selva2.webframework.annotation.Required; import static org.selva2.webframework.ActionUtil.*; public class AddAction { public static class AddParams extends RequestParams { @Label("引かれる数") @Required @IntegerType public String arg1; @Label("引く数") @Required @IntegerType public String arg2; } @RequestScope public Integer result; @Default public ActionResult execute() { return forward("/WEB-INF/view/add/input.jsp"); } @Event public ActionResult calculate(AddParams param) { if (param.isValidationError()) { // (1) return forward("/WEB-INF/view/add/input.jsp", param); // (2) } result = Integer.parseInt(param.arg1) + Integer.parseInt(param.arg2); // (3) return forward("/WEB-INF/view/add/result.jsp"); // (4) } }
Actionクラスは、何かをextends, implementsしようかと思いましたが、結局POJO的になりました。
URLとアクションクラスの紐づき
URLとActionクラスは、規約により結びつきます。Actionクラスのメソッドには、結びつきません。
URL
http://localhost:8080/webapp/add
が、webapp.action.AddActionクラス に結びついてる感じです。
URLをカスタマイズする方法も妄想していますが、アノテーションでカスタマイズするのではなく、slim3みたいな設定クラスにしようかと思っています。そっちの方が、URLとクラスの紐づきが追いやすいかと。
リクエストパラメータの受け取り
内部クラスのAddParamsが、リクエストパラメータを受け取るクラスです。外部のクラスでも構いません。RequestParamsを継承します。
で、メソッドの引数で渡される感じです。
メソッドアノテーション
Default
通常コールされるメソッドを指定します。
Event
メソッド名称と同じ名前のリクエストパラメータが存在する場合、コールされます。サブミットボタンのname属性に対応する感じです。
フィールドアノテーション
Label
エラーメッセージに出力するラベル名称を指定します。langも以下の感じで指定可能。
@Label("ほげ", "ja") @Label("hoge", "en") public String hoge;
Labelアノテーションを指定しない場合、フィールド名称がラベル名称として扱われます。
Required, IntegerType
SAStrutsと同じ感じのバリデーション。
RequestScope
Actionメソッドが、コールされる前に、フィール名称でrequest.getAttributeされたオブジェクトがバインドされます。また、Actionメソッドがコールされた後に、request.setAttributeされます。デフォルトでフィールド名称が使われるが、以下のように変更することも可能
@RquestScope("FUGA") public String hoge;
ActionResultクラス
メソッドの戻り値の型です。フォワード、リダイレクト等を指定します。
派生クラスで、Forward, Redirect, Json, Xmlとか。
その他
- (1)でバリデーションエラーが発生してるかチェックします。エラー発生の画面遷移は、自動で行われず、コードで指定します。
- (2)でフォワードしています。引数で、paramを渡していますが、これによりリクエストパラメータが、リクエストスコープに展開されます。バリデーションエラー時に、入力内容が消えないようにしています。
- (3)ですが、StringをIntegerに変換しています。直接リクエストパラメータをIntegerで受け取れますが、最近リクエストパラメータは、Stringで受け取っておいた方が良いんじゃないかと考えいます。
- (4)では、paramを渡していません。計算結果の画面には、入力内容を表示しないためです。return forwardView("/add/result");のように簡潔にかけるようにしようとも考えています。
次回は、設定ファイルとJSP。