- PR -

iterateを使用してプロパティをtextタグの初期値に設定したい

投稿者投稿内容
うるるとさらら
会議室デビュー日: 2003/10/07
投稿数: 9
投稿日時: 2003-10-07 16:23
・・・こんがらがってきました。(本当にすいません)
でくのぼうさんの例を使い、試してみましたがうまくいきませんでした。
はじめの方で出ていた「シンボルを解決できません」のエラーがどうしても
出てしまいます。

ちなみにコードは以下のとおりに書きました。
-----------------------------------------------------------------------
<logic:iterate type="gijutsu.form.MenuForm" id="data"
             name="gijutsuMenuForm" property="kojinList">
<tr>
<th bgcolor="#CCCCCC">社員番号</th>
<td>
<html:text name="gijutsuMenuForm" property="kojinList"
value="<%=data.getVar1()%>" size="8" maxlength="10" /></td>
</tr>
</logic:iterate>
---------------------------------------------------------------------------
iterateタグのtype属性にはid属性で指定するBeanの型を設定と書いてあるの
ですが、でくのぼうさんの例でいくとクラス名を指定で間違っていませんよね?
色々入れ子に書くと属性の内容も変わってくるみたいですが、その部分も充分に
把握できずにいます・・・。

・・・アクションクラス・アクションフォームクラスの考え方が間違っているの
でしょうか。でもそうすると、<td>・・・</td>内でもデータは読み込めないはず
ですし・・・。ずっと格闘しているのですが、解決できません。

でくのぼう
大ベテラン
会議室デビュー日: 2003/10/06
投稿数: 162
投稿日時: 2003-10-07 17:15
あ、ごめんなさい。
iterate タグ内に type を定義しても <% %> 内には関係無かったです。

<logic:iterate id="data"
        name="gijutsuMenuForm" property="kojinList">
<bean:define id="d" name="data" type="gijutsu.form.MenuForm"/>
<tr>
<th bgcolor="#CCCCCC">社員番号</th>
<td>
<html:text name="gijutsuMenuForm" property="kojinList"
value="<%=d.getVar1()%>" size="8" maxlength="10" /></td>
</tr>
</logic:iterate>

これでどうでしょう?
<bean:define> を使うようにしました。

この中の type は data のクラス名を指します。
つまり kojinList の中身ですね。
※ これが fijutsu.form.MenuForm であるのか疑問です。違っていたら訂正してください。
でくのぼう
大ベテラン
会議室デビュー日: 2003/10/06
投稿数: 162
投稿日時: 2003-10-07 18:11
蛇足気味ではあるのですが、どうも ActionForm の使用方法が
変だなあと感じたので私なりに書き直してみたものを以下に記しておきます。

何らかの参考程度になれば幸いかと。

[ViewMenuAction.java]
------------------------------------------------------------------------------
List kojinList = new ArrayList();
String selectSyainSQL;

DBA db = new DBA();
db.open();

selectSyainSQL
  = "SELECT T001KojinKihon.SyainNo, M002Syozoku.SyozokuName,(省略)"

java.sql.ResultSet rs = db.getResultSet(selectSyainSQL);

while(rs.next()){
  SyainBean sb = new SyainBean();
  sb.setSyainNo(rs.getString("SyainNo"));
  sb.setSyozokuName(rs.getString("SyozokuName"));
  kojinList.add(sb);
}
db.close();

request.setAttribute("kojinList", kojinList);
... syain_view.jsp を表示する ActionForward を return
------------------------------------------------------------------------------
↑ActionForm で不特定多数の社員情報を渡すのは困難ですから
 List を渡すようにしてあります。

[SyainBean.java]
------------------------------------------------------------------------------
private String syainNo;
private String syozokuName;

... 以下 setter/getter は略
------------------------------------------------------------------------------
このクラスは StringsClass みたいなものですね。
おそらくこのようにした方がわかりやすいでしょう。

[syain_view.jsp]
------------------------------------------------------------------------------
<bean:define id="klist" name="kojinList" type="java.util.List"/>
<%-- ↑ request スコープから kojinList を klist として取り出し --%>

<%-- 社員の数だけ Form を作ってしまう --%>
<logic:iterate id="syain" name="klist" type="SyainBean">
<bean:define id="s" name="syain" type="package.name.SyainBean"/>

<html:form action="/NextActionPath/">

<html:text property="name" value="<%= s.getSyainNo() %>"/>
<html:text property="syozoku" value="<%= s.getSyozokuName() %>"/>

<html:submit value="変更?"/>

</html:form>

</logic:iterate>
------------------------------------------------------------------------------
↑ひとつの form に不特定多数の社員情報が入るのは辛いので
 社員の数だけ form を用意してあります。

[NextActionForm.java](上の jsp から呼び出されるアクションに使う ActionForm)
------------------------------------------------------------------------------
private String syainNo;
private String syozokuName;

... setter/getter 等は略
------------------------------------------------------------------------------
NextAction はこの ActionForm を受け取って
社員情報に何らかの変更を行います。(NextAction.java は割愛してます)

う〜ん、何もここまで書かなくて良かったか・・・。
でもまあせっかく書いたので・・・。


[ メッセージ編集済み 編集者: でくのぼう 編集日時 2003-10-07 18:15 ]
うるるとさらら
会議室デビュー日: 2003/10/07
投稿数: 9
投稿日時: 2003-10-07 20:15
でくのぼうさん、返信が遅くなりました。すいません。
あれからでくのぼうさんの例を元に試行錯誤しました。
はじめの内はエラーが出ていたのですが、以下の内容で
設定できました。

------------------------------------------------------------------------
<logic:iterate id="data" name="gijutsuMenuForm" property="kojinList" >
<tr><th bgcolor="#CCCCCC">社員番号</th>
<td>
<html:text name="data" property="var1" size="8" maxlength="10"/>
</td>
</logic:iterate>
------------------------------------------------------------------------
あぁ、bean:writeのときと同じ設定でできるのかぁ!!!!!
・・・申し訳ありません・・・(涙)

単純な方法がまったく頭に浮ばず、かってに難しく考えて、質問してしまった
ようです。ただ、でくのぼうさんやたーぞんさんの教えをきっかけに色々考え、
設定の方法などを学ぶことができたと思います。現在、表示したデータをhtml
上で変更し、そのデータをサーバに登録する部分に入っています。データの取得
方法にまた一難しそうですが、今回の一件を糧にして進めていこうと思います。

本当にありがとうございました。
でくのぼう
大ベテラン
会議室デビュー日: 2003/10/06
投稿数: 162
投稿日時: 2003-10-07 22:56
ええと達成感にひたられているところ水をさすようで恐縮なんですが・・・。

<html:text> の name 属性には ActionForm を指定するように
期待されています。

そのため、うるるとさららさんのコードでは、動くには動くのですが
StringsClass を指定するのは Struts 的には実は NG なんですね。

name が省略された場合は、親タグである <html:form> に関連した
ActionForm がデフォルトで設定されている事になります。

では今回、このような NG 実装に至ってしまった根本的な問題点はと言うと
「ActionForm のプロパティが DB からの検索結果によって動的に変化する」
という点に尽きるかと思われます。

// 先ほどの私の長いコードは ActionForm のプロパティを動的にしない例です。

http://jakarta.apache.org/struts/userGuide/building_controller.html#map_action_form_classes

こちらに解説が載っているのですが(また英語です。ごめんなさい。)
動的なプロパティを実装するための手段として ActionForm 内に
Map や List を用意する方法が紹介されています。

この方法を踏襲する事で今回の問題は、データの取得も含めて
氷解すると思われます。

やや最初の頃と論点がズレていると感じられるかもしれませんが
Struts タグライブラリを普通の形式で利用していないという事は
どこか設計段階でミスがあると言えるはずです。

特に ActionForm の設計が私の目から見ますと、やや不自然な実装に
なっていますので、ぜひこの方法も検討の視野に入れてみてください。
通りすがりの野次馬
会議室デビュー日: 2003/10/08
投稿数: 2
投稿日時: 2003-10-08 12:06
> ------------------------------------------------------------------------
> <logic:iterate id="data" name="gijutsuMenuForm" property="kojinList">
> <tr>
> <th bgcolor="#CCCCCC">社員番号</th>
> <td>
> <html:text name="gijutsuMenuForm" property="kojinList"
> value="<%=data.getVar1()%>" size="8" maxlength="10" /></td>
> </tr>
> </logic:iterate>
> ------------------------------------------------------------------------

iterateタグはnameとpropertyで指定されるコレクション内のBeanを
idで指定した名前の変数として取出し、ボディ部を1回ずつ評価するものです。

したがって上の例では
<logic:iterate id="data" name="gijutsuMenuForm" property="kojinList">は
gijutsuMenuFormのメソッドgetKojinList()によりコレクションを取得し、
そのコレクション内にあるBeanを1つずつ取出し、</logic:iterate>までを評価する
ものですね。

value属性に値を埋め込みたい場合は<bean:define>タグを使用する方法がよいと思います。
以下のように修正するとよいでしょう。

------------------------------------------------------------------------
<logic:iterate id="data" name="gijutsuMenuForm" property="kojinList">
<tr>
<th bgcolor="#CCCCCC">社員番号</th>
<td>
<bean:define id="dataVar1" name="data"
property="var1" type="java.lang.String"/>
<html:text name="gijutsuMenuForm" property="kojinList"
value="<%=dataVar1%>" size="8" maxlength="10" /></td>
</tr>
</logic:iterate>
------------------------------------------------------------------------
これでdataが持っている値を<html:text>タグのvalue属性に設定することが出来ます。
ただし<bean:define>タグは指定したプロパティがnullである場合はエラーとなりますので
注意が必要です。

あと1点気になるのは<html:text>タグのproperty属性にkojinListを指定していることです。
kojinListはコレクションを指しますよね?<html:text>タグのproperty属性にはString型の
プロパティを指定しなければなりませんが、gijutsuMenuForm内に入力値に関連付けるプロパティ
とそのgetter/setterメソッドが見当たらないのでエラーになるのだと思います。
gijutsuMenuFormに社員番号を表すString型のプロパティとそのgetter/setterメソッドを追加し、
<html:test>タグのproperty属性にそのプロパティを指定してやればうまく動くと思います。


通りすがりの野次馬
会議室デビュー日: 2003/10/08
投稿数: 2
投稿日時: 2003-10-08 13:14
自己レスです。とんでもない勘違いをしてましたので訂正します。

> gijutsuMenuFormに社員番号を表すString型のプロパティとそのgetter/setterメソッドを追加し、
> <html:text>タグのproperty属性にそのプロパティを指定してやればうまく動くと思います。

まったくのうそです。<html:text>タグは、コレクション内の個々のStringClassオブジェクトに
関連付けなければならないのでアクションフォームBeanにたった1個のプロパティを追加する
だけでいいはずはありません。

これに対応するには、まず、アクションフォームBeanに以下のようなメソッドを用意します。

-----------------------------------------------------------------------------
public StringClass getKojinInfo(int index){
return (StringClass)kojinList.get(index);
}

public void setKojinInfo(int index, StringClass sc){
kojinList.add(index, sc);
}
-----------------------------------------------------------------------------

そして、JSPを以下のように修正します。

-----------------------------------------------------------------------------
<logic:iterate id="data" name="gijutsuMenuForm"
property="kojinList" indexId="idx">
<tr>
<th bgcolor="#CCCCCC">社員番号</th>
<td>
<bean:define id="dataVar1" name="data"
property="var1" type="java.lang.String"/>
<html:text name="gijutsuMenuForm" property='<%="kojinInfo["+idx+"].var1"%>'>
value="<%=dataVar1%>" size="8" maxlength="10" /></td>
</tr>
</logic:iterate>
-----------------------------------------------------------------------------

インデックス付きプロパティを使用していますが、詳細な情報は以下のサイトを参考にしてください。
http://www.janit.com/TechnoInf/Java/Struts1.1b3/faqs/indexedprops.html
うるるとさらら
会議室デビュー日: 2003/10/07
投稿数: 9
投稿日時: 2003-10-08 14:32
>でくのぼうさん、

 *<html:text> の name 属性には ActionForm を指定するように
*期待されています。
*
*そのため、うるるとさららさんのコードでは、動くには動くのですが
*StringsClass を指定するのは Struts 的には実は NG なんですね。

 とあったため、でくのぼうさんが

 *// 先ほどの私の長いコードは ActionForm のプロパティを動的にしない例です。

 と提供して頂いた例を元にコードを書き換えたところ、うまくいきました!
 ただし、社員の数だけformを用意する部分は、コードを追加すると
 「logic:iterateタグが終了していません」とエラーが発生するため、はずして
 あります。おそらく、1つのjspで複数のリストを表示させる為に、最初に
 「html:form action="***"」宣言を行っているからだと思います。

 今後は、jspにあと2つの違うデータのリストを表示させるのと、そのデータの取得
 部分に入る予定です。

 動的なActionFormについては、紹介していただいたサイトと、「O'REILLY-
 プログラミングJakartaStruts」を参考に学習中です。

 大変きめこまかな指導、ありがとうございます!!!

>通りすがりの野次馬さん、

 indexIdプロパティについて、ご紹介して頂いたサイトより学習させて頂きます。
 書いて頂いた例に関しても、少し方向性は変わってしまいましたが、参考にさせて
 頂きます。ありがとうございましたm(^-^)m

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