S2Strutsの機能について説明します。
ActionFormとActionは、Strutsのクラスを継承して定義できますが、S2Strutsではそれらを継承せずにPOJOとして定義することもできます。
Actionには、適切なsetterメソッドによりSeasar2のコンポーネントをDIすることができます。
ただし、DIを行う前提として、ActionをコンポーネントとしてS2コンテナに登録しておく必要があります。
登録の方法については、Actionコンポーネントの登録を参照してください。
ActionFormのインスタンスはStrutsで管理されるため、ActionFormにはSeasar2のコンポーネントはDIされません。
またActionFormをS2コンテナに登録する必要はありません(原則的には登録しないでください)。
POJOのActionFormは、Strutsのorg.apache.struts.action.ActionForm を継承しないだけで、役割は同じです。HTMLのフォームに対応するプロパティを持つように定義してください。
public class AddForm {
private String arg1;
private String arg2;
private String result;
public String getArg1(){ return arg1; }
public void setArg1(String arg1){ this.arg1 = arg1; }
public String getArg1(){ return arg1; }
public void setArg2(String arg2){ this.arg2 = arg2; }
public String getArg2(){ return arg2; }
public void setResult(String result){ this.result = result; }
}
resetメソッド
次のシグネチャのメソッドが定義されている場合、ActionFormに値が設定される前に呼び出されます。
SessionスコープのActionFormを使う場合で、プロパティのリセットが必要な場合に使用してください。
public void reset();
POJOのActionは、Strutsのorg.apache.struts.action.Action を継承しないだけで、役割は同じです。
public class AddAction {
private AddForm addForm;
public void setAddForm(AddForm addForm) {
this.addForm = addForm;
}
public String calculate() {
int result = Integer.valueOf(addForm.getArg1())
+ Integer.valueOf(addForm.getArg2());
addForm.setResult(String.valueOf(result));
return "success";
}
}
アクションメソッドの定義
Actionにはリクエストに対応するメソッドを定義します。
メソッドのシグネチャは次のようなものをサポートしています(xxxは任意の名称です)。
Forwardが必要な場合、ActionForwardの名前を返す必要があります
アクションメソッドの呼び出し
アクションメソッドの呼び出しは、S2Strutsのタグライブラリを利用して呼び出すことができます。
<s2struts:submit action="@{add_addAction.calculate}">
calculate
</s2struts:submit>
自動バインディング
POJO Actionにsetterメソッドがある場合、アクションのメソッドが実行される前に、プロパティ名をキーとしてHttpServletRequest やHttpSession から取得した値がプロパティにインポートされます。
値の取得を試みる優先順位は次の通りです。
HttpServletRequest#getAttribute(プロパティ名)
HttpServletRequest#getParameter(プロパティ名)
HttpSession#getAttribute(プロパティ名)
また、POJO Actionにgetterメソッドがある場合、アクションのメソッドが実行された後で、プロパティの値がプロパティ名をキーとしてHttpServletRequest やHttpSession にエキスポートされます。
- デフォルトで、
HttpServletRequest#setAttribute(プロパティ名,プロパティ値) が実行されます
- アノテーションで指定された場合に限り、
HttpSession#setAttribute(プロパティ名,プロパティ値) が実行されます
@ExportToSession()
public String getFoo() {
return foo;
}
ActionFormのインポートとエクスポートもこの自動バインディングの仕組みを用いて行われます。
Actionのマッピング定義に登録する方法は大きく分けて2つあります。
struts-config.xmlに記述する方法と、記述しない方法です。
記述しない場合は、無設定Strutsという機能を使います。
struts-config.xmlに記述する方法
通常通り、Strutsでaction-mapping要素内にaction要素を記述する方法です。
<action
path="/add"
type="org.seasar.struts.examples.add.AddAction"
name="calcForm"
scope="request"
validate="false"
input="/pages/addInput.html"/>
<forward name="success" path="/pages/result.html" />
</action>
action要素のtype属性にActionProxy を指定する方法
<action
path="/add"
type="org.seasar.struts.action.ProxyAction"
name="calcForm"
scope="request"
validate="false"
input="/pages/addInput.html"/>
<forward name="success" path="/pages/result.html" />
</action>
S2Strutsで管理するコンポーネントはaction要素のpath属性に指定した名前で登録しておく必要があります。
action要素のtype属性に何も指定しない方法
<action
path="/add"
name="calcForm"
scope="request"
validate="false"
<forward name="success" path="/pages/result.html" />
</action>
S2Strutsで管理するコンポーネントはaction要素のpath属性に指定した名前で登録しておく必要があります。
この方法を利用する場合、action要素のtype属性、forward属性、include属性には何も指定してはいけません。
設定をアノテーションで記述します。無設定Strutsについては無設定Sturtsリファレンスを参照してください。
@StrutsActionForm
public class AddForm {
...
}
@StrutsAction(input = AddAction.ADD)
public class AddAction {
...
}
Actionクラスの数だけ設定を記述します。インスタンス属性はrequestにします。
<component class="org.seasar.struts.examples.add.AddAction" instance="request"/>
設定に従い、コンポーネントを一括で登録します。インスタンス属性はrequestにします。
<component
class="org.seasar.framework.container.autoregister.FileSystemComponentAutoRegister">
<property name="instanceDef">
@org.seasar.framework.container.deployer.InstanceDefFactory@REQUEST
</property>
<property name="autoNaming">
<component class="org.seasar.framework.container.autoregister.DefaultAutoNaming"/>
</property>
<initMethod name="addClassPattern">
<arg>"examples.action"</arg>
<arg>".*Action"</arg>
</initMethod>
</component>
この設定は、app.diconもしくはapp.diconにインクルードされるdiconファイルで行ってください。
詳しくはコンポーネントの自動登録を参照してください。
命名規約によりActionクラスのパッケージ名とクラス名を決定し、自動で登録されるようにします。
SMART deployについては、S2コンテナのドキュメントやHOT deployを参照してください。
HOT deployはSMART deployの1つのモードです。
org.seasar.struts.pojo.MessageManager クラスを利用すると任意のコンポーネントからエラーメッセージの表示を管理する事が可能になります。
MessageManager.addGlobalError("examplemessage");
MessageManager.addGlobalError("examplemessage", "foo");
MessageManager.addGlobalError("examplemessage", "bar", "baz", "qux");
MessageManager.addError("property", "examplemessage");
MessageManager.addError("property", "examplemessage", "foo");
MessageManager.addError("property", "examplemessage", "bar", "baz", "qux");
MessageManager.saveErrors();
これは、StrutsのActionクラスで実装する以下のコードとほぼ同意です。
ActionMessages errors = new ActionMessages();
errors.add(ActionErrors.GLOBAL_MESSAGE,new ActionMessage("examplemessage"));
errors.add(ActionErrors.GLOBAL_MESSAGE,new ActionMessage("examplemessage", "foo"));
errors.add(ActionErrors.GLOBAL_MESSAGE,new ActionMessage("examplemessage", "bar", "baz", "qux"));
errors.add("property",new ActionMessage("examplemessage"));
errors.add("property",new ActionMessage("examplemessage", "foo"));
errors.add("property",new ActionMessage("examplemessage", "bar", "baz", "qux"));
if(!errors.isEmpty()) {
saveErrors(request,errors);
}
"ほぼ"同意と記述した理由は、上記で利用するリソースのキーexamplemessageの中に、{4}などが含まれていた場合にそれを削除する機能がMessageManagerには備わっている為です。
また、MessageManagerは、メッセージを管理するためのaddGlobalMessage()、addMessage()メソッドや、saveMessages()メソッドも備えています。
引数などはエラーメッセージを扱う場合と同じです。
HOT deployの説明についてはSMART deployを参照してください。
HOT deployを利用したサンプルとしてはS2StrutsExample V1.3.xやS2StrutsBlank V1.3.xを使用してください。
これらの利用法についてはS2Strutsのセットアップを参照してください。
HOT deployを利用するにはServlet2.4が必要です。
S2Strutsでは、次のものをHOT deployの対象にできます。
- SMART deployの規約に従ったSeasar2のコンポーネント
- struts-config.xml
- validation.xml
- struts-config.xmlに指定するメッセージ用のプロパティファイル
HOT deployを利用するには次の設定を確認してください。
- 必要なdiconファイル
次のdiconファイルがクラスパス上に存在している必要があります。
- env.txt
-
条件インクルードを利用するためにenv.txtをクラスパスに追加します。
env.txtには「ct」と記述します。
運用環境ではブランクもしくは「product」と記述しHOT deployは使用しないようにしてください。
ct
- app.dicon
- struts-config.xml
-
S2RequestProcessor やS2TilesRequestProcessor を利用している場合は、
controllerにcatalogを指定し、プロパティでACTION_CONTEXT_CLASS にS2Strutsのクラスを指定します。
S2RequestProcessor やS2TilesRequestProcessor はHOT deployに完全対応していないため、Commons Chainを利用するこの設定が必要です。
<controller catalog="s2struts">
<set-property
key="ACTION_CONTEXT_CLASS"
value="org.seasar.struts.processor.contexts.S2ServletActionContext"/>
</controller>
-
plug-inに
org.seasar.struts.hotdeploy.plugin.HotdeployPlugIn を追加します。
<plug-in
className="org.seasar.struts.hotdeploy.plugin.HotdeployPlugIn"/>
- web.xml
HotdeployFilter を追加します。dispatcherの指定を正確に行ってください。
<filter>
<filter-name>hotdeployfilter</filter-name>
<filter-class>
org.seasar.framework.container.hotdeploy.HotdeployFilter
</filter-class>
</filter>
...
<filter-mapping>
<filter-name>hotdeployfilter</filter-name>
<url-pattern>/*</url-pattern>
<dispatcher>REQUEST</dispatcher>
<dispatcher>FORWARD</dispatcher>
<dispatcher>INCLUDE</dispatcher>
</filter-mapping>
S2StrutsHotdeployFilter を追加します。
<filter>
<filter-name>s2strutshotdeployfilter</filter-name>
<filter-class>
org.seasar.struts.hotdeploy.filter.S2StrutsHotdeployFilter
</filter-class>
</filter>
...
<filter-mapping>
<filter-name>s2strutshotdeployfilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
|