Struts の DynaActionForm で、複数の項目によるプロパティを扱うには
表題だけでは何のことか分からないと思いますが、画面上では複数の入力項目であるが、フォームのプロパティとしては一つである場合のようなパターンです。
たとえば、Web アプリで画面上の入力項目として、下記の例のように、郵便番号を配達局番号と町域番号に分けて表示したいとします。
(HTML例) 郵便番号: -
これを、素直に Struts の HTML タグを使用した JSP で記述すると以下のようになると思います。
(JSP 例 - 変更前) <html:form action="/Test"> 郵便番号: <html:text property="postOfficeCode"/> - <html:text property="townAreaCode"/> </html:form>
この入力フォームに対応する Struts のフォーム定義を DynaActionForm を使用して記述した場合、以下のようになると思います。
(フォーム定義 - 変更前) <form-bean name="testForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="postOfficeCode" type="java.lang.String"/> <form-property name="townAreaCode" type="java.lang.String"/> </form-bean>
上記のようなフォーム定義で何か問題があるわけではないです。
しかし、私の場合、最終的にドメインモデルへマッピング*1することを考えると、意味的に一つの項目は、一つのプロパティとしてまとまっていて欲しいと思うのです。
そこで、以下のような郵便番号を表す JavaBeans *2を用意して、フォームのプロパティとして使用します。
(郵便番号JavaBeans) public class PostalCode implements java.io.Serializable { private String postOfficeCode; private String townAreaCode; // セッタ、ゲッタの記述を省略 }
フォームの定義は以下。
(フォーム定義例 - 変更後 1) <form-bean name="testForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="postalCode" type="PostalCode"/> </form-bean>
このままでは、HTML フォーム内の入力項目と値のやり取りが出来ないので、JSP の記述も以下のようにします。
(JSP 例 - 変更後) <html:form action="/Test"> 郵便番号: <html:text property="postalCode.postOfficeCode"/> - <html:text property="postalCode.townAreaCode"/> </html:form>
Sturts ではネストしたプロパティへのアクセスを、プロパティ名を '.'(ドット) で繋ぐことで行なえるようになっています。そこで、入力項目のプロパティ名を、フォームのプロパティ名 + ドット + 郵便番号JavaBeans内プロパティ名 とすることで、対象となるJavaBeansの各プロパティに値を設定できます。
この状態のままでも問題は無いのですが、郵便番号を表す JavaBeans を作成するのも( ゜Д゜)マンドクセーだとなった場合、フォーム定義を以下のようにすることで郵便番号を表す JavaBeans を使う必要がなくなります。*3
(フォーム定義 - 変更後 2) <form-bean name="testForm" type="org.apache.struts.action.DynaActionForm"> <form-property name="postalCode" type="org.apache.commons.beanutils.LazyDynaBean"/> </form-bean>
プロパティの型を BeanUtil に含まれている LazyDynaBean にすることで、必要に応じてプロパティが追加されます。
Struts がフォームに対して、postalCode.postOfficeCode プロパティを設定しようとした場合、postOfficeCode プロパティが LazyDynaBean オブジェクトに追加され、同様にpostalCode.townAreaCode プロパティを設定しようとした場合には townAreaCode プロパティが追加されるというわけです。