- PR -

Strutsのリスト形式の入力画面でのValidatorを用いた入力チェック

1
投稿者投稿内容
獅子丸
会議室デビュー日: 2004/08/11
投稿数: 3
投稿日時: 2004-08-11 17:20
 Strutsでリスト形式の入力画面を実装しているのですが、Validatorをもちいて入力チェックを行う所で躓いてしまい、大変困っています。

 具体的な実装方法は以下の通りです。

 ValidatorFormを実装したActionFormクラスは2つ用意してあります。
・form1 … 検索情報入力フィールド、追加情報入力フィールド、リスト表示のためのListクラスのインスタンス、ページめくりのための各種情報(ページ情報、表示件数情報)
・form2 … 1レコードの情報

 form1のListクラスのインスタンス内に、form2が格納されているイメージです。

 form1の追加情報入力フィールドと、form2の1レコードの情報は入力チェックを行いたいので、Validator設定ファイル(Validation.xml)にそれぞれ作成しました。

 Struts設定ファイルの内容は次の通りです。
(略)
<!-- List -->
<action path="/ListDispatch"
type="ListDispatchAction"
name="form1"
scope="session"
input="/jsp/List.jsp"
parameter="action"
validate="false">
<set-property property="loginRequired" value="true" />
<forward name="display" path="/ListDisp.do?pageflow=search" />
<forward name="go" path="/List.do?pageflow=go" />
<forward name="start" path="/List.do?pageflow=start" />
<forward name="previous" path="/List.do?pageflow=previous" />
<forward name="next" path="/List.do?pageflow=next" />
<forward name="end" path="/List.do?pageflow=end" />
<forward name="add" path="/Add.do" />
<forward name="save" path="/Save.do" />
</action>

<action path="/List"
type="ListAction"
name="form1"
input="/jsp/List.jsp"
scope="session"
validate="true">
<set-property property="loginRequired" value="true" />
<forward name="success" path="/jsp/List.jsp" />
</action>

<action path="/ListDisp"
type="ListAction"
name="from1"
input="/jsp/List.jsp"
scope="session"
validate="false">
<set-property property="loginRequired" value="true" />
<forward name="success" path="/jsp/List.jsp" />
</action>

<action path="/Add"
type="AddAction"
name="from1"
input="/jsp/List.jsp"
scope="session"
validate="true">
<set-property property="loginRequired" value="true" />
<forward name="success" path="/jsp/List.jsp" />
</action>

<action path="/Save"
type="SaveAction"
name="from1"
input="/jsp/List.jsp"
scope="session"
validate="ture">
<set-property property="loginRequired" value="true" />
<forward name="success" path="/jsp/List.jsp" />
</action>

(略)


 画面の動きですが、まず、最初に画面を開いたときには、検索情報入力フィールドと表示ボタン、レコード追加情報入力フィールドと追加ボタンのみが表示されます。

 表示ボタンを押すことで、検索情報を元に、テキストボックスの入力項目を持つリストと、ページめくり様ボタン、更新ボタンが表示されます。

 追加ボタンを押すことで、追加情報がリストに表示されます。
 このとき、まだDBへの保存は行われません。
 更新ボタンが押されたとき、はじめて保存が行われます。

 リストのテキストボックスの内容を変更し、更新ボタンを押すことで、その変更が保存されます。

 入力チェックを行うタイミングは以下の通りです。
1、追加ボタンを押したとき、追加情報についてチェックを行う。
2、ページめくりボタンを押したとき、リストのレコード情報についてチェックを行う。
3、更新ボタンが押されたとき、リストのレコード情報についてチェックを行う。

 これをJavaScriptとサーブレットでの2重のチェックを行います。

 これを想定し、今回はform1とform2の両方のチェックを行うので、JSPには以下の記述をしました。
<html:javascript formName="form1" />
<html:javascript formName="form2" />

 また、チェックするフィールドが動的な上に、ボタンによってチェックする場所も異なってくるので、

<html:submit property="action"
onclick=" return validateForm1(this.form);">
<bean:message key="button.common.add"/>
</html:submit>

<html:submit property="action"
onclick=" return validateForm2(this.form);">
<bean:message key="button.common.go"/>
</html:submit>

 というように、ボタンのアクションによってValidatorを発行するという、少々イレギュラーな使い方をしています。

 さて、実際に実行してみると、サーブレット側では、レコード情報を格納したform2のValidatorは行われず、form1のValidatorは行われていました。

 また、Javascriptはエラーが起こり、入力チェックは行われませんでした。
 これは、<html:javascript>を複数記述したため、同名の変数が上書きされてしまい、エラーが起こっているもようです。


 ここまできて、自分で思いつく限界がきたようで、まったく歯が立たなくなってしまいました。
 解決案、代替案、もしくは仕様のまずさや実装への指摘、何でも構いませんので、どうかご教授願います。
hypergori
会議室デビュー日: 2004/01/20
投稿数: 19
投稿日時: 2004-08-11 21:21
獅子丸さんの内容を熟読してないし、あとvalidatorの仕様の確認もしてない
思いつきの返答ですが、
問題は2つなきがします。

1.validator javascriptを2回よんでる。
validatorでは これはできない気がする。

2.Listの項目 のclient side validationは対応してないはず。serversideのみできる。

まず、validatorのjava scriptは、同時にかけないと思うというとこからですが、

対処法としては、pageをつかってvaliateする項目を振り分ける FormBeanを1つにする。
1つめの submit では hiddenを使用して page=1というものをなげる
validator xmlないの 項目のタグにpage=1をかく、
そうするとそのボタンのときだけチェックしたい項目だけがチェックされる。

もうひとつのボタンのほうにはどうように hiddenを使用して page=2もサブミットして
validator xmlないの 項目のタグにpage=2 をかく、

共通のチェック項目には、pageをしていしなけえれば 両方のSUBMITのときにチェックがはいる。

1つ問題は、 page 2 のときにチェックには、page 1のチェックも行われるので
すこし工夫が必要です(Wizard系のページ遷移でFormビーンが1個のイメージっぽい)。

validatorのソースをみると、
if (validator.xml の page < サブミットされたpage ) {
妥当性チェックを行う
}

とりあえず page属性を調べてみれば なにか 解決するかも。
あと リスト項目に入っているビーンのプロパティのValidationを
クライアントサイドでやるのは、むりだとおもいます。そういうロジックが
Validator-rule.xmlのJavascriptにないから。つくればできるとおもいますが
できたら Jakartaに 送ってやってください。

上記は、確認してないので、 古い情報かもしれませんが。そのときはご容赦を。










[ メッセージ編集済み 編集者: hypergori 編集日時 2004-08-11 21:22 ]
獅子丸
会議室デビュー日: 2004/08/11
投稿数: 3
投稿日時: 2004-08-12 17:20
 ご回答ありがとう御座います。

 やはり、リスト形式の画面に対しては、ローカルでのチェックは独自にJavaScriptを実装しなければならないようですね。

 まあ、考えてみれば当然かもしれません。
 リストのように動的に項目が増える物に対して、ボタン一つで入力チェックを行おうとすれば、Javascriptの動きは重くなるでしょうから。

 ちなみに、サーバサイドのリストの入力チェックが行われないのを回避するために、わざわざActionクラスでValidatorを呼び出して処理することにしました。
 正直、基本的な入力チェックが分散するのは、保守性の問題があるように感じるのですが、とりあえず今はこれで妥協します。

 ありがとうございました。
獅子丸
会議室デビュー日: 2004/08/11
投稿数: 3
投稿日時: 2004-08-13 16:27
 スレッドを乱立させるのはあまり好ましくないと思いますので、関連があるこちらのスレッドで再び質問いたします。

 前回、結局サーブレット側だけでのチェックを行うと決定し、実装に取り掛かったのですが、サーブレット側でリストの内部のActionFormのvalidateメソッドを、Action実装クラスで明示的に呼び出すようにしておけば、ValidatorFormの入力チェックが行えると思い、実際に行ってみました。

 ところが、validateメソッドを呼び出した瞬間にNullPointerExceptionが生じてしまい、処理が続きませんでした。
 ValidatorFormの143行目でエラーが起きているようなので、ソースを確認しようと思いましたが、どうやら取得したソースがおかしかったらしく、143行目にはstacktraceが示すようなvalidateメソッドは存在しなく、resetメソッドの「}」があるだけでした。

 エラーを追及するために、新しいStrutsのバイナリデータとソースをダウンロードし、実行しようとすると、何故か同じActionクラスを数回実行した後にOutOfMemoryErrorが発生するので、古いJarファイルに戻しました。

 古い方と新しい方の違いは、struts-legacy.jarがあるか無いかの違いだけに見えたので、古い方に合わせてstruts-legacy.jarを削除すると、新しいのはまったく動かなくなりました。

 古い方も新しい方も、どちらもStrutsの1.1で、大した違いは無いはずなのですが…

 ともかく、どうにも確認ができなかったので、なぜ明示的にValidatorFormのvalidateメソッドを呼び出すと、NullPointerExceptionが発生するのか、どなたかご存知の方はご教授ください。

 また、余力があれば、新しいStrutsを導入した際に生じるようになってしまったOutOfMemoryErrorの原因をお教えいただければ幸いです。
1

スキルアップ/キャリアアップ(JOB@IT)