リクエストパラメータの格納先
Struts2では、ブラウザからのリクエストをActionクラスへ反映します。リクエストパラメータ名と同じフィールド名に対して値を格納します。
例えば http://localhost:8080/sampleApp/start.action?userid=ZZ12345&username=capybara がリクエストされたときに、StartActionクラスが動作する場合では、以下の動作をします。
- ブラウザから呼び出すActionクラスは start.action にマッピングされたActionクラスを実行する
- リクエストパラメータは userid , username の2つ
これを受け取るActionクラスは以下のようになります。
public class StartAction extends ActionSupport {
@Action("start")
public String start() throws Exception {
return SUCCESS;
}
@Getter @Setter
private String userid;
@Getter @Setter
private String username;
}
- @Action は Struts2-Conventionプラグインのアノテーション
- @Getter @Setter は project lombokのアノテーションで、フィールドに対するgetメソッド、setメソッドを提供します。
パラメータに過不足があった場合の振る舞い
- リクエストに対するActionクラスが存在しなかった場合は、Struts2の標準エラー画面になります。
- リクエストパラメータに対するActionクラスのフィールドとget/setメソッドがなかった場合は、そのパラメータは破棄されます。
- 開発モードがONのときは、「リクエストパラメータに対するフィールドが存在しない」旨の警告がメッセージに追加されます。
パラメータを別のクラスへ渡せる
Actionクラスにパラメータ用のフィールドをすべて用意すると、個数に応じてActionクラスのコードが長くなり、パラメータの変更があるたびにActionクラスを修正しなければならないので、メンテナンス性が悪くなります。
そこでStruts2では、Actionのフィールドに、値を格納するためのクラスを置けるようにしています。Struts1時代のActionFormのようなものですね。
先ほどの例から、useridとusernameを格納するクラスをUserDtoとします。
@Data
public class UserDto {
private String userid;
private String username;
}
@Dataはlombokのアノテーションです。すべてのフィールドに対しget/setメソッドを付与し、toString()メソッドの実装も提供します。
これを扱うActionクラスは次のようになります。
public class StartAction extends ActionSupport {
@Action("start")
public String start() throws Exception {
return SUCCESS;
}
@Getter @Setter
private UserDto user;
}
Actionクラスのuserフィールドに、UserDtoを格納します。
少しすっきりしましたね。
ただし、Actionクラスのフィールド名を変更してしまい、UserDtoの内部へuseridやusernameを移動したため、先ほどのURLでは送信できません。
Actionクラスの userフィールドが持っているuseridとusername であるため、リクエストパラメータの名前を次のように変更します。
このようにStruts2では、JavaScriptのようにクラスの階層をたどって値を格納しようと試みます。
しかしパラメータ名を毎回 fieldAAAAA.fieldBBBB のように記述するのは冗長だし、fieldAAAAAの部分は1種類しかない場合、Struts2にはこれを省略できる ModelDriven / ScopedModelDriven と呼ばれる拡張機能が使えます。
ModelDriven / ScopedModelDrivenについてはまた別途。