11. DynaActionForm
11.1. org.apache.struts.action.DynaActionForm
ActionFormクラスを用いると、パラメータ毎にsetter/getterメソッドを作成しなければなりません。DynaActionFormはその手間を改善する、ActionFormのサブクラスです。DynaActionFormを使用すると、パラメータ毎にsetter/getterメソッドを作成する必要がありません。しかしStrutsのカスタムタグにおいては、ActionFormと同じように扱う事ができます。つまり指定されたプロパティに対するgetterメソッドが無くても、<bean:write>タグなどでプロパティ値が取り出されるように作られています。ここではまずDynaActionFormをそのまま使用する場合について説明します。
まずStruts設定ファイルにDynaActionFormの設定を記述します。
... <struts-config> <form-beans> <form-bean name="dyna" type="org.apache.struts.action.DynaActionForm"> <form-property name="name" type="java.lang.String" initial="" /> <form-property name="price" type="int" initial="0" /> </form-bean> ...
<form-bean>タグの中で、<form-property>を定義する点がこれまでと異なります。<form-property>はDynaActionFormが受け取るパラメータ(DynaActionFormが持つプロパティ)を指定するもので、「name」属性でパラメータ名、「type」属性でパラメータの型、「initial」属性で初期値を指定します。name属性とtype属性は必須です。以下にtype属性に指定できる値をまとめたものです。
- java.lang.String
- int (java.lang.Integer)
- long (java.lang.Long)
- short (java.lang.Short)
- float (java.lang.Float)
- double (java.lang.Double)
- boolean (java.lang.Boolean)
- byte (java.lang.Byte)
- char (java.lang.Character)
- java.sql.Date
- java.sql.Time
- java.sql.Timestamp
- java.lang.BigDecimal
- java.lang.BigInteger
- java.lang.Class
- 配列
- java.util.Mapを実装したクラス
- java.util.Listを実装したクラス
initial属性を省略した場合には、数字は0に、オブジェクトはnullに初期化されます。
続いてActionクラスでDynaActionFormを使用します。ここでは先ほど、Struts設定ファイルに設定したプロパティを読み取っています。
package sample; import javax.servlet.http.*; import org.apache.struts.action.*; public class ProductInputAction extends Action{ public ActionFormward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{ DynaActionForm dynaForm=(DynaActionForm)form; String name=(String)dynaForm.get("name"); Integer price=(Integer)dynaForm.get("price"); ... } }
値の取得には「get」メソッドを用います。3種類の「get」メソッドがありますが、通常は引数が1つのものを使用します。以下に定義を示します。引数としてプロパティ名を指定すると、その値が返されます。返り値の型はjava.lang.Objectですので、適切な型にキャストして使用します。もしプロパティがなかったり、Struts設定ファイルで指定されたプロパティの型が不正な場合には例外が発生します。
Object get(String name)
続いて、プロパティの型が配列である場合について説明します。プロパティの型に配列を指定する場合は、initial属性で各要素の初期値を与えるか、size属性で配列の要素数を指定する必要があります。そこで指定した要素数の配列が作成されます。ですから、initial/size属性のいずれも指定しなかった場合には、要素数0の配列となってしまうので意味がなくなります。
initial属性で初期値を与える場合は、各要素を「'」で囲み、要素間を「,」で区切ります。「'」で囲まなくても初期値を与える事ができますが、空文字列の場合にはその部分が無視されてしまいます。空文字列で初期化したい場合には、必ず「'」で囲むようにして下さい。
<form-bean name="dyna" type="org.apache.struts.action.DynaActionForm"> <form-property name="address" type="java.lang.String[]" initial="'Kyoto','Sakyo-ku',''" /> ...
size属性で要素数を指定した場合には、各要素が0またはnullに初期化されます。
<form-bean name="dyna" type="org.apache.struts.action.DynaActionForm"> <form-property name="shops" type="java.lang.String[]" size="3" /> ...
DynaActionFormから配列のプロパティ値を取得する場合には、以下のgetメソッドを使用します。引数が1つのgetメソッドで配列を取得してから、配列の各要素にアクセスしても構いません。
Object get(String name, int index)
先ほど定義したプロパティを取得する場合は、以下のようになります。
DynaActionForm dynaForm=(DynaActionForm)form; String shop1=dynaForm.get("shops", 0); String shop2=dynaForm.get("shops", 1);
プロパティの型がjava.util.List(の実装クラス)である場合も上記と同じです。ただしListを使用する場合には、Struts設定ファイルで初期値やリストの初期サイズを与えることができません。従ってActionクラスなどで初期値を与える工夫をしなければ、<html:text>で使用することができません。
プロパティの型がjava.util.Mapである場合も、Struts設定ファイルで初期値を与えることができません。しかし<html:text>でもエラーが発生しないようになっています。なおMapの値をDynaActionFormから取得する場合には、以下のgetメソッドを使用します。
Object get(String name, String key)
例えば以下のようになります。引数が1つのgetメソッドで、Mapを取り出す方法もあります。
String telSales=dynaForm.get("tel", "home"); String telOffice=dynaForm.get("tel", "company");
DynaActionFormはJakarta-CommonsのBeanUtilsライブラリをベースに作成されています。また「org.apache.commons.beanutils.BeanUtils」の「copyProperties」メソッドで、DynaActionFormのプロパティを他のJava Beanのプロパティにコピーすることができます。
(実習課題1)
6章実習課題3のWebアプリケーションを改良しなさい。
- DynaActionFormをそのまま使用すること。
- パラメータのチェック機能は解除して良い。