6. فرمهای HTML
تا اینجا، ما از یک فرم واحد متشکل از تنها دو فیلد ورودی استفاده کردهایم. در اینجا، ما پیشنهاد میکنیم که یک فرم را با استفاده از اجزای گرافیکی استاندارد (دکمههای رادیویی، چکباکسها، فیلدهای ورودی، کادرهای ترکیبی، لیستها) ایجاد و پردازش کنیم.
6.1. نمایهای برنامه
این برنامه تنها دو نما خواهد داشت. نمای اول یک فرم خالی را نمایش میدهد:
QZXW2HTMLP000547ZQX 1 - formulaire

این نمای اول، با نام formulaire.jsp، به ما امکان میدهد تا تگهای مختلفی را از کتابخانهٔ struts-html پیادهسازی کنیم. کاربر فرم را پر میکند:

دکمه [Envoyer] تأیید مقادیر واردشده را فراهم میکند. این نمای دوم خواهد بود:

این نمای دوم به ما امکان میدهد از دو کتابخانه تگ دیگر استفاده کنیم: struts-bean و struts-logic. لینک [Retour au formulaire] به ما اجازه میدهد به فرم به همان شکلی که پر شده بود بازگردیم. سپس به نمای اول بازمیگردیم.
6.2. معماری برنامه
![]() |
- فرم (نما ۱) توسط یک شیٔ پویا از Struts به نام dynaFormulaire، از نوع مشتقشده از DynaActionForm، نمایش داده خواهد شد. این فرم توسط نما formulaire.jsp نمایش داده میشود.
- اکشن Struts با شناسه InitFormulaireAction مسئول بازیابی دادههای مورد نیاز برای نمایش فرم خواهد بود
- فرم تکمیلشده توسط اکشن ForwardAction پردازش خواهد شد که به سادگی درخواست را به نمای دوم confirmation.jsp هدایت میکند. این نما مسئول نمایش مقادیر فرم خواهد بود.
6.3. پیکربندی برنامه
6.3.1. فایل server.xml
زمینهٔ برنامه /form2 نامگذاری خواهد شد. بنابراین خط زیر را به فایل Tomcat با نام server.xml اضافه خواهیم کرد:
پس از انجام این کار، ممکن است لازم باشد Tomcat را مجدداً راهاندازی کنیم تا زمینهٔ جدید را شناسایی کند. میتوانیم با درخواست http://localhost:8080/formulaire2 URL بررسی کنیم که معتبر است:

6.3.2. فایل web.xml
فایل پیکربندی برنامه، web.xml، به شرح زیر خواهد بود:
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE web-app
PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
</web-app>
در مورد فایلهای پیکربندی web.xml که قبلاً با آنها مواجه شدهایم، چند تغییر ایجاد میکنیم:
- ما دو کتابخانه تگ جدید معرفی میکنیم: `struts-bean` و `struts-logic`. این کتابخانهها در ویوی `confirmation.jsp` استفاده خواهند شد. ویوی `formulaire.jsp` از سوی دیگر از کتابخانه `struts-html` استفاده خواهد کرد.
6.3.3. فایل struts-config.xml
فایل struts-config.xml به شرح زیر خواهد بود:
<?xml version="1.0" encoding="ISO-8859-1" ?>
<!DOCTYPE struts-config PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_1.dtd">
<struts-config>
<form-beans>
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
<form-property name="chk1" type="java.lang.String"/>
<form-property name="chk2" type="java.lang.String"/>
<form-property name="chk3" type="java.lang.String"/>
<form-property name="champSaisie" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="boiteSaisie" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="listeSimple" type="java.lang.String"/>
<form-property name="listeMultiple" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
</form-beans>
<action-mappings>
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/vues/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
</action-mappings>
<message-resources
parameter="ApplicationResources"
null="false"/>
</struts-config>
این شامل سه بخش اصلی است:
- اعلامیههای فرم در بخش <form-beans>
- اعلام اکشنها در بخش <action-mappings>
- اعلام فایل منابعی در بخش <message-resources>
6.3.4. ابجکتهای فرم برنامه (بیینها)
ابجکتهای مورد استفاده برای نمایش فرمهای HTML برنامه از نوع ActionForm یا یکی از انواع مشتقشده (DynaActionForm، DynaValidatorForm و غیره) هستند. آنها به دلیل اینکه مطابق با قواعد JavaBeans ساخته شدهاند، «بِین» نامیده میشوند. در برنامه ما تنها یک بِین فرم وجود دارد که dynaFormulaire نامیده میشود و از DynaActionForm مشتق شده است. این بِین در شرایط زیر استفاده خواهد شد:
- برای نگهداری دادههای مورد نیاز برای نمایش نما شماره ۱
- بازیابی مقادیر از فرم در نمای شمارهٔ ۱ هنگام ارسال آن توسط کاربر
- برای نگهداری دادههای مورد نیاز برای نمایش نمای شماره ۲
ساختار بیان dynaFormulaire ارتباط نزدیکی با فرم در نمای شماره ۱ دارد. بیایید این موضوع را بررسی کنیم:
![]() |
خیر. | نوع HTML | نقش |
<input name="opt" type="radio" value="yes"> <input name="opt" type="radio" value="no"> | گروه دکمههای رادیویی مرتبط (با نام یکسان) | |
<input name="chk1" type="radio" value="on"> <input name="chk2" type="radio" value="on"> <input name="chk3" type="radio" value="on"> | گروههایی از چکباکسها (نام یکسان نیست) | |
<input type="text" name="champSaisie" > | یک فیلد ورودی | |
<input type="password" name="mdp"> | یک فیلد رمز عبور | |
<textarea name="boiteSaisie">...</textarea> | یک فیلد متن چندخطی | |
<select name="combo" size="1">..</select> | یک منوی کشویی | |
<select name="listeSimple" size="3">..</select> | فهرست انتخاب تکگانه | |
<select name="listeMultiple" size="3" multiple>..</select> | فهرست چندگانه | |
<input type="button" value="Clear" onclick='clearList("simpleList")'> | دکمه برای لغو انتخاب موارد انتخابشده در listeSimple (7) | |
<input type="button" value="پاک کردن" onclick='clearList("multipleList")'> | دکمه برای لغو انتخاب موارد انتخابشده در listeMultiple (8) | |
<input type="submit" value="ارسال"> | دکمه ارسال فرم | |
<input type="hidden" name="secret" value="..."> | یک فیلد مخفی |
بیایید چند مورد را بررسی کنیم:
- شیء dynaFormulaire برای نگهداری مقادیر فرم HTML که از طریق دکمه [Envoyer] ارسال خواهد شد، استفاده میشود. بنابراین باید دارای همان فیلدها باشد که در فرم HTML وجود دارد. نوع فیلد بر اساس قاعده زیر تعیین میشود:
- اگر فیلد HTML تنها یک مقدار ارائه دهد، آنگاه فیلد در dynaFormulaire از نوع java.lang.String خواهد بود
- اگر فیلد HTML چندین مقدار ارائه دهد، آنگاه فیلد dynaFormulaire از نوع java.lang.String[] خواهد بود
در فرم HTML بالا، تنها فیلد listeMultiple احتمالاً با مقادیر چندگانه (مقادیر انتخابشده توسط کاربر) مرتبط خواهد بود. بنابراین، تعریف اولیهٔ شیء dynaFormulaire به شرح زیر خواهد بود:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
<form-property name="chk1" type="java.lang.String"/>
<form-property name="chk2" type="java.lang.String"/>
<form-property name="chk3" type="java.lang.String"/>
<form-property name="champSaisie" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="boiteSaisie" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="listeSimple" type="java.lang.String"/>
<form-property name="listeMultiple" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
</form-bean>
چگونه dynaFormulaire با مقادیر فرم HTML که توسط کلاینت وب ارسال شده است، پر خواهد شد؟
میدان «opt» در صورتی که فیلد HTML <input type="radio" name="opt" value="yes"> انتخاب شده باشد، روی «yes» تنظیم میشود و در صورتی که فیلد <input type="radio" name="opt" value="no"> انتخاب شده باشد، روی «no» تنظیم میشود. | |
میدان «chk1» در صورتی که گزینه HTML <input name="chk1" type="radio" value="1"> تیک خورده باشد، روی «on» تنظیم میشود؛ در غیر این صورت، خالی باقی میماند. در حالت دوم، میدان «chk1» مقدار قبلی خود را حفظ خواهد کرد. | |
به همین ترتیب | |
همان | |
میدان champSaisie متنی را که کاربر در میدان HTML <input type="text" name="champSaisie"> وارد میکند، دریافت خواهد کرد. این متن میتواند یک رشتهٔ خالی باشد. | |
میدان 'mdp' متنی را که کاربر در میدان HTML <input type="password" name="mdp"> وارد میکند، دریافت خواهد کرد. این متن میتواند یک رشته خالی باشد. | |
میدان boiteSaisie متنی را که کاربر در میدان HTML <textarea name="boiteSaisie">...</textarea> وارد میکند، دریافت خواهد کرد. این متن یک رشتهٔ کاراکتری واحد است که از خطوط تایپشده توسط کاربر تشکیل شده و با توالی کاراکتر "\r\n" از یکدیگر جدا شدهاند. متن حاصل ممکن است در برخی موارد یک رشتهٔ خالی باشد. | |
کادر ترکیبی مقدار گزینهای را که کاربر در فیلد HTML <select name="combo" size="1">..</select> انتخاب کرده است، دریافت میکند. گزینهٔ انتخابشده همان گزینهای است که در کادر ترکیبی نمایش داده میشود. اگر گزینه انتخابشده HTML از نوع <option value="XX">YY</option> باشد، کادر ترکیبی مقدار "XX" را دریافت خواهد کرد. اگر گزینهٔ انتخابشده HTML از نوع <option>YY</option> باشد، فیلد کشویی روی مقدار "YY" تنظیم خواهد شد. | |
میدان listeSimple بر اساس گزینهای که کاربر در میدان HTML <select name="listeSimple" size="..">..</select> انتخاب کرده است، تنظیم خواهد شد. اگر هیچ گزینهای وجود نداشته باشد، فیلد listeSimple هیچ ارزشی دریافت نمیکند و مقدار قبلی خود را حفظ میکند. مقداری که در واقع به فیلد listeSimple اختصاص مییابد، از قوانین مشخصشده برای لیست کشویی پیروی میکند. | |
میدان listeMultiple (از نوع String[]) گزینههای انتخابشده توسط کاربر را در میدان HTML <select name="listeMultiple" size=".." multiple>..</select> در صورت وجود، دریافت خواهد کرد. اگر هیچ گزینهای انتخاب نشود، آرایه listeMultiple هیچ مقداری دریافت نمیکند و محتویات آن بدون تغییر باقی میماند. مقادیری که در واقع به آرایه listeMultiple اختصاص مییابند، از قوانین مشخصشده برای لیست کشویی پیروی میکنند. | |
میدان «secret» با مقدار XX از میدان HTML <input type="hidden" name="secret" value="XX"> تنظیم خواهد شد. این متن میتواند یک رشته خالی باشد. |
- شیء dynaFormulaire برای ارائه محتوای اولیه برای نما شماره ۱ استفاده میشود. مقادیر فیلدهای قبلی برای اهداف زیر استفاده خواهند شد:
باید روی «بله» یا «خیر» تنظیم شود تا مرورگر بداند کدام دکمه رادیویی را انتخاب کند | |
اگر chk1 روی «on» تنظیم شود، تیکجعبه تیکخورده خواهد شد؛ در غیر این صورت، تیکخورده نخواهد شد. | |
به همین ترتیب | |
همانند بالا | |
مقدار فیلد در فیلد ورودی champSaisie نمایش داده خواهد شد | |
مقدار فیلد در فیلد ورود رمز عبور نمایش داده خواهد شد | |
مقدار فیلد در فیلد ورودی نمایش داده خواهد شد boiteSaisie | |
مقدار این فیلد مشخص میکند که کدام مورد در لیست کشویی هنگام نمایش فرم باید انتخاب شود | |
همانند بالا | |
مقادیر جدول listeMultiple مشخص میکند که کدام موارد در لیست چندگزینهای هنگام نمایش فرم باید انتخاب شوند | |
مقدار این فیلد به ویژگی «value» فیلد مخفی HTML اختصاص داده میشود. |
نما شماره ۱ به اطلاعات بیشتری نیاز دارد:
- فهرست مقادیری که باید در لیست کشویی نمایش داده شوند
- فهرست مقادیری که باید در لیست listeSimple نمایش داده شود
- فهرست مقادیری که باید در لیست listeMultiple نمایش داده شوند
چندین روش برای ارائه این اطلاعات به ویو وجود دارد. برای مثال، آرایههایی که در درخواست ارسال شده به ویو گنجانده میشوند، کار را راه میاندازند. در اینجا، این آرایهها را در بیون dynaFormulaire قرار میدهیم:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
...
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
فرم dynaFormulaire توسط اکشن /init اولیه میشود، که یک شی مشتقشده از Action به نام InitFormulaireAction را فراخوانی میکند. این شیء مسئول ایجاد سه آرایهٔ مورد نیاز برای نمایش سه لیست و قرار دادن آنها در بین dynaFormulaire خواهد بود. فایل پیکربندی دامنه این بین را روی 'session' تنظیم میکند. در نتیجه، کنترلکننده Struts این بین را در جلسه (session) قرار خواهد داد. این بدان معناست که ما نیازی به بازتولید آن بین بین چرخههای درخواست-پاسخ نخواهیم داشت. در نتیجه، اکشن /init تنها یک بار فراخوانی خواهد شد.
- شیء dynaFormulaire همچنین برای ارائه محتوای نما شماره ۲ استفاده میشود. این نما صرفاً مقادیر را نمایش میدهد.
6.3.5. اقدامات برنامه
اقدامات توسط اشیاء از نوع Action یا کلاس مشتقشده از آن مدیریت میشوند. اقدامات در داخل تگهای <action-mappings> پیکربندی میشوند:
<action-mappings>
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/vues/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
</action-mappings>
توجه داشته باشید که همیشه یک فرم با یک اکشن مرتبط نیست. این مورد، همانطور که در بالا نشان داده شده است، برای اکشن /affiche صدق میکند. قبل از پرداختن به جزئیات هر اکشن، بیایید به یاد بیاوریم که جفت اکشن-فرم چگونه در داخل تگ <action> کار میکند:
- یک اکشن با درخواستی از سوی کلاینت وب آغاز میشود و با ارسال یک صفحه پاسخ به پایان میرسد. این چرخه درخواست-پاسخ وب کلاینت-سرور است. درخواست توسط کنترلکننده Struts از نوع ActionServlet یا نوع مشتقشده از آن دریافت میشود. همچنین همین کنترلکننده است که پاسخ را ارسال میکند.
- بیان فرم (form bean) از نوع ActionForm یا نوع مشتق شده از آن، اگر از قبل وجود نداشته باشد، ایجاد میشود. کنترلکننده بررسی میکند که آیا میتواند یک شیء با نام 'name' را در دامنه مشخصشده توسط 'scope' پیدا کند. اگر چنین باشد، از آن استفاده میکند. اگر نه، آن را ایجاد کرده و در دامنه مشخصشده توسط 'scope'، مرتبط با ویژگی مشخصشده توسط 'name'، قرار میدهد.
برای مثال، در مثال اکشن /init، کنترلر تابع request.getSession().getAttribute("dynaFormulaire") را برای تعیین اینکه آیا dynaFormulaire قبلاً ایجاد شده است یا خیر، اجرا خواهد کرد. اگر اینطور نباشد، آن را ایجاد کرده و با استفاده از دستوری مانند request.getSession() به جلسه اضافه خواهد کرد.setAttribute("dynaFormulaire", new DynaFormulaire(...)).
- کنترلکننده همچنین به دنبال یک شیء Action از نوع مشخصشده توسط ویژگی 'type' خواهد گشت. اگر نتواند آن را پیدا کند، آن را ایجاد میکند؛ در غیر این صورت، از آن استفاده میکند.
- متد reset دانه فرم فراخوانی خواهد شد. این دانه، به جز هنگام ایجاد اولیه، دوباره استفاده میشود. بنابراین حاوی دادههایی است که ممکن است بخواهید «پاکسازی» کنید. این کار در داخل متد reset دانه ActionForm یا یک کلاس مشتق شده از آن انجام میشود.
- اگر اکشن مقصد یک فرم ارسالشده باشد، مقادیر فرم موجود در درخواست کلاینت در فیلدهای با نام مشابه در فرمبین کپی میشوند. توجه داشته باشید که متد reset پیش از این کپی فراخوانی شده است.
- اگر پیکربندی ویژگی `validate="true"` را مشخص کند، متد `validate` در فرمبین فراخوانی میشود. این متد سپس باید دادههای موجود در فرمبین را اعتبارسنجی کند. این اعتبارسنجی معمولاً فقط زمانی انجام میشود که فرم به تازگی از طریق یک درخواست POST دادههای جدیدی دریافت کرده باشد و نیاز باشد که اعتبار این دادهها بررسی شود. این متد هر فهرستی از خطاها را در یک شیء ActionErrors به کنترلر بازمیگرداند.
- اگر شیء ActionErrors خالی نباشد، کنترلکننده نمایی را که توسط ویژگی `input` اکشن مشخص شده است، نمایش میدهد.
- اگر اعتبارسنجی دادهها درخواست نشده باشد یا با موفقیت انجام شده باشد، کنترلکننده متد `execute` شیء از نوع `Action` (یا یک کلاس مشتق شده) مرتبط با اکشن جاری را اجرا میکند. در همین متد است که درخواست کلاینت وب پردازش میشود. متد `execute` یک شیء `ActionForward` را بازمیگرداند که کلیدهای رشتهای دارد. این کلیدها، کلیدهایی هستند که توسط تگهای فوروارد (forward tags) اکشن پیکربندیشده تعریف شدهاند. در مثال ما، اکشن /init یک تگ فوروارد واحد دارد. این تگ، کلید «afficherFormulaire» را با نمای formulaire.jsp مرتبط میسازد.
- کنترلکننده نمایی را که با کلید دریافتی مرتبط است نمایش میدهد. این نما در واقع میتواند یک اکشن باشد، که در این صورت فرآیند قبلی تکرار میشود.
اقدام /init
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
- عمل /init معمولاً یکبار در طول اولین چرخه درخواست-پاسخ رخ میدهد، زمانی که کاربر URL http://localhost:8080/formulaire2/init.do را درخواست میکند
- شیء dynaFormulaire ایجاد یا بازیافت میشود. این شیء (در حالت بازیافت) بازیابی یا (در حالت ایجاد) در جلسه قرار میگیرد، همانطور که توسط ویژگی scope مشخص شده است.
- متد ریست آن فراخوانی میشود. باید چه کاری انجام دهد؟ معمولاً فیلدهای شیء ActionForm به مقادیر پیشفرض خود بازنشانی میشوند. با این حال، در این مورد این کار را انجام نخواهیم داد، زیرا شیء dynaFormulaire در جلسه قرار داده شده است (scope="session"). بنابراین فیلدهای dynaFormulaire باید مقادیر خود را حفظ کنند. این مقادیر هنگام ایجاد اولیهٔ شیء dynaFormulaire چه هستند؟ دو حالت وجود دارد:
- این فیلد دارای مقدار اولیه مشخصشده در فایل پیکربندی است:
در این حالت، کنترلکننده Struts این فیلد را با این مقدار اولیه ایجاد خواهد کرد.
- برای این فیلد هیچ مقدار اولیه مشخص نشده است: قوانین инициализация جاوا اعمال میشوند. به طور کلی، فیلدهای عددی مقدار صفر، رشتههای کاراکتری مقدار رشته خالی و سایر اشیاء مقدار null خواهند داشت.
بیایید به پیکربندی اولیه برای dynaFormulaire نگاهی بیندازیم:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
<form-property name="chk1" type="java.lang.String"/>
<form-property name="chk2" type="java.lang.String"/>
<form-property name="chk3" type="java.lang.String"/>
<form-property name="champSaisie" type="java.lang.String" initial=""/>
<form-property name="mdp" type="java.lang.String" initial=""/>
<form-property name="boiteSaisie" type="java.lang.String" initial=""/>
<form-property name="combo" type="java.lang.String"/>
<form-property name="listeSimple" type="java.lang.String"/>
<form-property name="listeMultiple" type="java.lang.String[]"/>
<form-property name="secret" type="java.lang.String" initial="xxx"/>
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
مقادیر اولیه فیلدهای dynaFormulaire پس از ایجاد به شرح زیر خواهد بود:
میدان | مقدار اولیه |
"no" | |
رشته خالی | |
رشته خالی | |
رشته خالی | |
رشته خالی | |
رشته خالی | |
رشته خالی | |
آرایهای از رشتههای خالی | |
"xxx" | |
آرایه از رشتههای خالی |
- ممکن است تصور شود که متد reset در dynaFormulaire، آرایههای سهگانه را که سه لیست در نمای formulaire.jsp را تغذیه میکنند، پر میکند. این امر در اینجا ممکن است زیرا دادههای این سه آرایه به صورت دلخواه تولید میشوند. با این حال، سناریوی رایجتر این است که این دادهها از مدل کاربردی، یعنی «M» در MVC، آمده باشند. در اینجا، برای سادهتر کردن مثال، ما یک راه میانه را در پیش میگیریم و این مقادیر را توسط اکشن InitFormulaireAction تولید میکنیم — یعنی توسط C در MVC.
- نیازی به نوشتن یک متد ریست در dynaFormulaire نیست، زیرا کلاس ActionForm که از آن مشتق شده است، از قبل دارای چنین متدی است که هیچ کاری انجام نمیدهد (بدون هیچگونه inicialization).
- پس از فراخوانی متد ریست dynaFormulaire، کنترلر ویژگی validate اکشن را بررسی میکند. در اینجا، مقدار آن «false» است. متد validate dynaFormulaire فراخوانی نخواهد شد.
- شیء InitFormulaireAction ایجاد میشود، یا در صورت وجود قبلی بازیافت میشود، و متد `execute` آن فراخوانی میشود. این متد است که مقادیر دلخواه را به سه آرایه dynaFormulaire: valeursCombo، valeursListeSimple و valeursListeMultiple تخصیص میدهد. این متد یک ActionForward با کلید «afficherFormulaire» را بازمیگرداند.
- کنترلکننده نمای /vues/formulaire.jsp را نمایش میدهد که از طریق برچسب forward از اکشن /init با کلید «afficherFormulaire» مرتبط شده است.
/تأیید
<action
path="/confirmation"
name="dynaFormulaire"
validate="false"
scope="session"
parameter="/vues/confirmation.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- عمل تأیید / زمانی آغاز میشود که کاربر دکمه [Envoyer] را در نما شماره ۱ کلیک کند. سپس مرورگر فرم را، همانطور که توسط کاربر تکمیل شده است، به کنترلر Struts ارسال میکند.
- شیء dynaFormulaire از جلسه بازیابی میشود
- متد reset آن فراخوانی میشود. پس از فراخوانی این متد، کنترلر Struts مقادیر فیلدهای فرم ارسالشده توسط کلاینت را در فیلدهای همنام در dynaFormulaire کپی میکند. بیایید دوباره به لیست فیلدهای مورد دوم نگاه کنیم و ببینیم این کپیسازی چگونه انجام میشود:
میدان | کد مرتبط HTML | مقدار فیلد پس از کپی کردن مقادیر فرم |
<input type="radio" name="opt" value="yes">بله <input type="radio" name="opt" value="no" checked="checked">خیر | - «بله» یا «خیر» بسته به دکمهی رادیویی انتخابشده | |
<input type="checkbox" name="chk1" value="on"> | - "on" اگر تیک چکباکس chk1 زده شده باشد - اگر تیک کادر chk1 زده نشده باشد، مقدار قبلی خود را حفظ میکند | |
<input type="checkbox" name="chk2" value="on"> | - "on" اگر کادر تیک chk2 تیک خورده باشد - اگر تیک کادر chk2 زده نشده باشد، مقدار قبلی خود را حفظ میکند | |
<input type="checkbox" name="chk2" value="on"> | - "on" اگر کادر تیک chk3 تیک خورده باشد - در صورتی که تیک چکباکس chk3 زده نشده باشد، مقدار قبلی خود را حفظ میکند | |
<input type="text" name="champSaisie" value=""> | - مقداری که توسط کاربر در champSaisie وارد شده است | |
<input type="password" name="mdp" value=""> | - مقداری که کاربر در mdp وارد میکند | |
<textarea name="boiteSaisie"></textarea> | - مقداری که کاربر در boiteSaisie وارد میکند | |
<select name="combo">...</select> | - مقداری که توسط کاربر در combo انتخاب شده است | |
<select name="listeSimple" size="3">...</select> | - مقداری که توسط کاربر در listeSimple انتخاب شده است | |
<select name="listeMultiple" multiple="multiple" size="5"> | - آرایهای از رشتهها حاوی مقادیر انتخابشده توسط کاربر در listeMultiple | |
<input type="hidden" name="secret" value="xxx"> | - "xxx". |
ما با مشکلی در فیلدهایی مواجه هستیم که لزوماً در درخواست ارسالشده توسط مرورگر، مقداری دریافت نمیکنند. این موضوع در مورد چکباکسهای chk1 تا chk3 و دو لیست listeSimple و listeMultiple صدق میکند. در این حالت، این فیلدها مقادیر قبلی خود را که در چرخه درخواست-پاسخ قبلی به دست آمدهاند، حفظ میکنند.
برای مثال، بیایید چکباکس chk1 را در نظر بگیریم و فرض کنیم که در چرخه درخواست-پاسخ قبلی، کاربر این باکس را تیک زده بود. در آن صورت، مرورگر اطلاعات chk1="on" را در رشته پارامترهای درخواست خود ارسال میکرد. بنابراین، توسعهدهنده مقدار "on" را به فیلد chk1 از dynaFormulaire اختصاص داد. حال فرض کنید که در چرخه فعلی، کاربر تیک کادر انتخاب chk1 را نمیزند. در این صورت، مرورگر در رشته پارامترهای درخواست جدید، چیزی مانند chk1="off" را ارسال نمیکند، بلکه هیچ چیزی ارسال نمینماید. در نتیجه، فیلد chk1 در dynaFormulaire مقدار «on» خود را حفظ خواهد کرد و بنابراین مقداری خواهد داشت که بازتابدهنده مقدار فرم ارسالشده توسط کاربر نیست. برای حل این مشکل از متد reset در dynaFormulaire استفاده خواهیم کرد. در این روش، ما سه فیلد chk1، chk2 و chk3 را روی «off» تنظیم خواهیم کرد. در مثال ما با chk1، کاربر میتواند:
- تیک کادر chk1 را میزند. در این صورت، مرورگر اطلاعات chk1="on" را ارسال میکند و فیلد chk1 در dynaFormulaire به "on" تغییر خواهد کرد
- تیک کادر chk1 را نمیزند. در این حالت، مرورگر هیچ ارزشی برای فیلد chk1 ارسال نمیکند، که این فیلد ارزش قبلی خود یعنی «off» را حفظ میکند. در هر دو حالت، ارزش ذخیرهشده در فیلد chk1 از dynaFormulaire صحیح است.
این مشکل برای هر دو لیست listeSimple و listeMultiple یکسان است. اگر هیچ گزینهای از این لیستها انتخاب نشده باشد، آنها در پارامترهای پرسوجو ظاهر نخواهند شد و بنابراین مقادیر قبلی خود را حفظ خواهند کرد. در متد ریست dynaFormulaire، listeSimple را به یک رشتهٔ خالی و listeMultiple را به یک آرایهٔ رشتهای با طول 0 ریست میکنیم.
- پس از فراخوانی متد ریست dynaFormulaire، کنترلکننده اطلاعات ارسالشده در درخواست کلاینت را مجدداً در فیلدهای dynaFormulaire کپی میکند
- یک شیء ForwardAction ایجاد یا بازیافت میشود و متد `execute` آن فراخوانی میشود. ForwardAction یک کلاس از پیش تعریفشده است که یک شیء ActionForward را بازمیگرداند که به ویوی تعریفشده توسط ویژگی «parameter» اکشن اشاره میکند، که در این مورد /vues/confirmation.jsp است.
- کنترلر این نما را ارسال میکند. چرخه کامل میشود.
اقدام /displays
<action
path="/affiche"
parameter="/vues/formulaire.jsp"
type="org.apache.struts.actions.ForwardAction"
/>
- عمل /display با کلیک روی لینک [Retour vers le formulaire] در نما شماره 2 فعال میشود.
- هیچ فرم مرتبطی با این اقدام وجود ندارد. بنابراین بلافاصله به اجرای متد `execute` یک شیء `ForwardAction` میپردازیم که یک شیء `ActionForward` را بازمیگرداند که به نمای `/vues/formulaire.jsp` اشاره میکند.
6.3.6. فایل پیام برنامه
بخش سوم فایل struts-config.xml، فایل پیامها است:
فایل ApplicationResources.properties در WEB-INF/classes قرار دارد. این فایل خالی خواهد بود. با اینکه خالی است، باید همچنان در فایل پیکربندی اعلام شود؛ در غیر این صورت، کتابخانه تگ struts-bean—که کمی بعد به آن خواهیم پرداخت—خطایی تولید خواهد کرد. این کتابخانه توسط ویوی confirmation.jsp استفاده میشود.
6.4. کد نما
6.4.1. ویوی formulaire.jsp
به یاد داشته باشید که این نما در دو حالت نمایش داده میشود:
- وقتی اکشن /init در اولین چرخه درخواست-پاسخ فراخوانی میشود
- وقتی اکشن /affiche در چرخههای درخواست-پاسخ بعدی فراخوانی میشود
کد نمای formulaire.jsp به شرح زیر است:
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html>
<head>
<title>formulaire</title>
</head>
<body background='<html:rewrite page="/images/standard.jpg"/>'>
<h3>Formulaire Struts</h3>
<hr>
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<table border="0">
<tr>
<td>bouton radio</td>
<td>
<html:radio name="dynaFormulaire" property="opt" value="oui">Oui</html:radio>
<html:radio name="dynaFormulaire" property="opt" value="non">Non</html:radio>
</td>
</tr>
<tr>
<td>Cases à cocher</td>
<td>
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox>
<html:checkbox name="dynaFormulaire" property="chk2">2</html:checkbox>
<html:checkbox name="dynaFormulaire" property="chk3">3</html:checkbox>
</td>
</tr>
<tr>
<td>Champ de saisie</td>
<td>
<html:text name="dynaFormulaire" property="champSaisie" />
</td>
</tr>
<tr>
<td>Mot de passe</td>
<td>
<html:password name="dynaFormulaire" property="mdp" />
</td>
</tr>
<tr>
<td>Boîte de saisie multilignes</td>
<td>
<html:textarea name="dynaFormulaire" property="boiteSaisie" />
</td>
</tr>
<tr>
<td>Combo</td>
<td>
<html:select name="dynaFormulaire" property="combo">
<html:options name="dynaFormulaire" property="valeursCombo"/>
</html:select>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td>Liste à sélection unique</td>
</tr>
<tr>
<td>
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
</td>
</tr>
</table>
<td>
<html:select name="dynaFormulaire" property="listeSimple" size="3">
<html:options name="dynaFormulaire" property="valeursListeSimple"/>
</html:select>
</td>
</tr>
<tr>
<td>
<table>
<tr>
<td>Liste à sélection multiple</td>
</tr>
<tr>
<td>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
</td>
</tr>
</table>
</td>
<td>
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true">
<html:options name="dynaFormulaire" property="valeursListeMultiple"/>
</html:select>
</td>
</tr>
</table>
<html:hidden name="dynaFormulaire" property="secret"/>
<br>
<hr>
<html:submit>Envoyer</html:submit>
</html:form>
</body>
</html>
این صفحه، JSP، از تگهای کتابخانه struts-html استفاده میکند. به یاد داشته باشید که برای استفاده از یک کتابخانه تگ، باید:
- آن را در فایل web.xml برنامه با استفاده از تگ <tag-lib> اعلام کنید
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
- کد این کتابخانه را در بخشی از ساختار دایرکتوری برنامه قرار دهید، در این مورد WEB-INF/struts-html.tld
- استفاده از این کتابخانه را در ابتدای صفحات JSP که از آن استفاده میکنند، اعلام کنید:
ویوی formulaire.jsp از تگها استفاده میکند که اکنون آنها را توضیح میدهیم:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |||
تگ html:rewrite به شما امکان میدهد نام برنامه را در URL حذف کنید. این تگ یک ویژگی دارد:
همانطور که در بالا نشان داده شده است، اگر تصمیم بگیرید نام برنامه را 'formulaire3' بگذارید، نیازی به بازنویسی کد ویژگی background نیست. تگ html:rewrite کد جدید HTML را تولید خواهد کرد. background="/formulaire3/images/standard.jpg" |
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire"> | |||||||
برچسب html:form برای تولید برچسب فرم HTML استفاده میشود. این برچسب چندین ویژگی دارد:
میتوانیم ببینیم که، به طور پیشفرض، کد تولید شده HTML از متد POST استفاده میکند. در همین کد، HTML، متد URL اقدام، بازنویسی شده است تا با نام برنامه پیشوند و با .do پسوند داده شود. |
<html:radio name="dynaFormulaire" property="opt" value="yes">بله</html:radio> | |||||||
تگ html:radio برای تولید تگ HTML <input type="radio" ...> استفاده میشود. این تگ از ویژگیهای مختلفی پشتیبانی میکند:
متن بین تگهای آغاز و پایان، متنی است که در کنار دکمه رادیویی نمایش داده میشود. |
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox> | |||||||
برچسب html:checkbox برای تولید برچسب HTML <input type="checkbox" ...> استفاده میشود. این برچسب از ویژگیهای مختلفی پشتیبانی میکند:
متن بین تگهای آغاز و پایان، متنی است که در کنار چکباکس نمایش داده میشود. |
<html:text name="dynaFormulaire" property="champSaisie" /> | |||||||
برچسب html:text برای تولید برچسب HTML <input type="text" ...> استفاده میشود. این برچسب از ویژگیهای مختلفی پشتیبانی میکند:
|
<html:password name="dynaFormulaire" property="mdp" /> | |
تگ html:password برای تولید تگ HTML <input type="password" ...> استفاده میشود. این تگ از ویژگیهای مختلفی پشتیبانی میکند: |
<html:textarea name="dynaFormulaire" property="boiteSaisie" /> | |||||||
برچسب <html:textarea> برای تولید برچسب <HTML> <textarea>...</textarea> استفاده میشود. این برچسب از ویژگیهای مختلفی پشتیبانی میکند:
|
<html:select name="dynaFormulaire" property="combo">....</html:select> | |||||||
تگ <html:select> برای تولید تگ <select>...</select> استفاده میشود. این تگ از ویژگیهای مختلفی پشتیبانی میکند:
|
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="valeursCombo"/> </html:select> | |||||
برچسب HTML:options برای تولید برچسبهای HTML <option>...</option> درون برچسب HTML <select> استفاده میشود. راههای مختلفی برای مشخص کردن نحوهٔ یافتن گزینههای منوی کشویی وجود دارد. در اینجا از ویژگیهای name و property استفاده کردهایم:
|
دو لیست دیگر به روشی مشابه لیست قبلی ایجاد میشوند:
<html:select name="dynaFormulaire" property="listeSimple" size="3">
<html:options name="dynaFormulaire" property="valeursListeSimple"/>
</html:select>
در مثال بالا، یک ویژگی size غیر از 1 مشخص شده است تا یک لیست به جای یک کادر کشویی نمایش داده شود.
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true">
<html:options name="dynaFormulaire" property="valeursListeMultiple"/>
</html:select>
در بالا، ویژگی multiple="true" برای ایجاد یک لیست با انتخاب چندگانه مشخص شده است.
<html:hidden name="dynaFormulaire" property="secret"/> | |||||
تگ html:hidden برای تولید تگ HTML <input type="hidden" ...> استفاده میشود.
|
برای درک کامل ارتباط بین نمای formulaire.jsp و بین dynaFormulaire که نماینده آن در حافظه است، مهم است به یاد داشته باشید که بین dynaFormulaire هم برای خواندن و هم برای نوشتن استفاده میشود:
![]() |
درخواست زمانی فعال میشود که کاربر دکمه [Envoyer] را در فرم کلیک کند. سپس مرورگر فرم HTML را به اقدام /confirmation ارسال میکند. ما قبلاً توضیح دادهایم که در این مرحله چه اتفاقی میافتد، بهویژه اینکه فیلدهای موجود در dynaFormulaire مقادیر فیلدهایی با همان نام در فرم HTML را دریافت خواهند کرد.
چه اتفاقی میافتد وقتی کنترلکننده درخواست میکند که نمای formulaire.jsp در پاسخ به یک درخواست نمایش داده شود؟ بیایید برچسبها را یکییکی بررسی کنیم:
<body background="<html:rewrite page="/images/standard.jpg"/>"> | |
کد HTML را تولید میکند |
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire"> ... </html:form> | |
کد HTML را تولید میکند |
<html:radio name="dynaFormulaire" property="opt" value="yes">بله</html:radio> <html:radio name="dynaFormulaire" property="opt" value="no">خیر</html:radio> | |
اگر فیلد «opt» از dynaFormulaire روی «yes» تنظیم شود، کد HTML را تولید کنید. |
<html:checkbox name="dynaFormulaire" property="chk1">1</html:checkbox> <html:checkbox name="dynaFormulaire" property="chk2">2</html:checkbox> <html:checkbox name="dynaFormulaire" property="chk3">3</html:checkbox> | |
اگر فیلدهای chk1 و chk3 از dynaFormulaire روی «on» تنظیم شده و فیلد chk2 روی «off» تنظیم شده باشد، کد HTML را تولید کنید. |
<html:text name="dynaFormulaire" property="champSaisie" /> | |
اگر فیلد champSaisie روی "this is a test" تنظیم شده باشد، کد HTML را تولید کنید. |
<html:password name="dynaFormulaire" property="mdp" /> | |
اگر فیلد 'mdp' روی 'azerty' تنظیم شود، کد HTML تولید میشود |
<html:password name="dynaFormulaire" property="mdp" /> | |
اگر فیلد «mdp» روی «azerty» تنظیم شود، کد HTML تولید میشود |
<html:password name="dynaFormulaire" property="mdp" /> | |
اگر فیلد 'mdp' روی 'azerty' تنظیم شود، کد HTML تولید میشود |
<html:select name="dynaFormulaire" property="combo"> <html:options name="dynaFormulaire" property="valeursCombo"/> </html:select> | |
اگر فیلد ترکیبی روی «combo2» تنظیم شود، کد HTML تولید میشود. |
<html:select name="dynaFormulaire" property="listeSimple" size="3"> <html:options name="dynaFormulaire" property="valeursListeSimple"/> </html:select> | |
اگر فیلد listeSimple روی "simple1" تنظیم شود، کد HTML تولید میشود. |
<html:select name="dynaFormulaire" property="listeMultiple" size="5" multiple="true"> <html:options name="dynaFormulaire" property="valeursListeMultiple"/> </html:select> | |
اگر فیلد listeMultiple آرایه {"multiple0","multiple2"} باشد، کد HTML را تولید میکند |
<html:hidden name="dynaFormulaire" property="secret"/> | |
اگر فیلد مخفی مقدار "xxx" را داشته باشد، کد HTML تولید میشود. |
<html:submit>ارسال</html:submit> | |
کد HTML را تولید میکند |
نکتهٔ پایانی که باید توضیح داده شود، کد جاوااسکریپت موجود در صفحهٔ JSP است که به دو دکمهٔ [Effacer] متصل شده و موارد انتخابشده در لیستهای listeSimple و listeMultiple را غیرفعال میکند:
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
برچسب
<html:form action="/confirmation" name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
کد HTML زیر را تولید میکند:
برای درک کد جاوااسکریپت مرتبط با دکمههای [Effacer]، بیایید به یاد بیاوریم که چگونه عناصر مختلف یک سند وب در کد جاوااسکریپتی که از آن سند استفاده میکند، ارجاع داده میشوند:
دادهها | معنی |
اشاره به کل سند وب دارد | |
اشاره به مجموعه فرمهای تعریفشده در سند دارد | |
اشاره به فرم شماره i در سند دارد | |
اشاره به فرم <form> با ویژگی 'name' که مقدار آن "nomFormulaire" است | |
اشاره به فرم <form> با ویژگی 'name' تنظیمشده روی "nomFormulaire" دارد | |
اشاره به مجموعه عناصری دارد که به فرم مشخصشده با عبارت [formulaire] تعلق دارند. این مجموعه شامل تمام تگهای <input>، <textarea> و <select> در فرم مذکور است. | |
به عنصر شماره i از [formulaire] اشاره دارد | |
اشاره به عنصری در [formulaire] دارد که ویژگی 'name' آن برابر با nomComposant است | |
اشاره به عنصر در [formulaire] دارد که ویژگی 'name' آن برابر با nomComposant است | |
اشاره به مقدار کامپوننت [composant] در فرم [formulaire] دارد، زمانی که کد HTML در آن فرم ممکن است دارای ویژگی value باشد (<input>, <textarea>) | |
به نمایه گزینهی انتخابشده در یک فهرست اشاره دارد. میتوان از آن هم برای خواندن و هم برای نوشتن استفاده کرد. تنظیم این خاصیت روی -1 تمام موارد فهرست را غیرفعال میکند. | |
اشاره به آرایه گزینههای مرتبط با تگ <select> دارد | |
اشاره به گزینه شماره i از تگ <select> مشخصشده دارد | |
یک مقدار بولی که نشان میدهد آیا گزینه شماره i از تگ <select> مشخصشده انتخاب شده (true) یا خیر. قابل استفاده برای خواندن و نوشتن |
بیایید بار دیگر به کد جاوااسکریپت مربوط به دو دکمه نگاه کنیم:
<input type="button" value="Effacer" onclick="this.form.listeSimple.selectedIndex=-1"/>
<input type="button" value="Effacer" onclick="this.form.listeMultiple.selectedIndex=-1"/>
وقتی دکمه کلیک میشود، کد مرتبط با ویژگی «onclick» اجرا میشود. در اینجا، این کد درونخطی است. معمولاً، ما onclick="function(...)" را مینویسیم، که در آن function یک تابع تعریفشده درون تگ <script language="javascript">...</script> است. کد بالا چه کاری انجام میدهد؟ بیایید کد مربوط به دکمه اول را توضیح دهیم:
اشاره به سند وبی دارد که دکمه در آن قرار دارد | |
اشاره به فرمی دارد که دکمه در آن قرار دارد | |
اشاره به کامپوننت listeSimple فرم دارد | |
اشاره به شاخص گزینه انتخابشده در listeSimple دارد. تنظیم این خاصیت روی -1 تمام گزینهها را غیرفعال میکند. |
6.4.2. نما confirmation.jsp
توجه داشته باشید که این نما پس از اقدام تأیید، c.a.d، و پس از ارسال فرم موجود در نما formulaire.jsp توسط کلاینت وب، نمایش داده میشود. هدف اصلی آن نمایش مقادیری است که کاربر وارد کرده است. کد آن به شرح زیر است:
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
<html>
<head>
<title>Confirmation</title>
</head>
<body background="<html:rewrite page="/images/standard.jpg"/>">
<h3>Confirmation des valeurs saisies</h3>
<hr/>
<table border="1">
<tr>
<td>Bouton radio</td>
<td><bean:write name="dynaFormulaire" scope="session" property="opt"/></td>
</tr>
<tr>
<td>Case à cocher chk1</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk1"/></td>
</tr>
<tr>
<td>Case à cocher chk2</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk2"/></td>
</tr>
<tr>
<td>Case à cocher chk3</td>
<td><bean:write name="dynaFormulaire" scope="session" property="chk3"/></td>
</tr>
<tr>
<td>Champ de saisie</td>
<td><bean:write name="dynaFormulaire" scope="session" property="champSaisie"/></td>
</tr>
<tr>
<td>Mot de passe</td>
<td><bean:write name="dynaFormulaire" scope="session" property="mdp"/></td>
</tr>
<tr>
<td>Boîte de saisie</td>
<td><bean:write name="dynaFormulaire" scope="session" property="boiteSaisie"/></td>
</tr>
<tr>
<td>combo</td>
<td><bean:write name="dynaFormulaire" scope="session" property="combo"/></td>
</tr>
<tr>
<td>liste simple</td>
<td><bean:write name="dynaFormulaire" scope="session" property="listeSimple"/></td>
</tr>
<logic:iterate id="choix" indexId="index" name="dynaFormulaire" property="listeMultiple">
<tr>
<td>liste multiple[<bean:write name="index"/>]</td>
<td><bean:write name="choix"/></td>
</tr>
</logic:iterate>
</table>
<br>
<html:link page="/affiche.do">
Retour au formulaire
</html:link>
</body>
</html>
در اینجا دو کتابخانه تگ جدید معرفی میکنیم: struts-bean و struts-logic. کتابخانه struts-bean دسترسی به اشیاء ذخیرهشده در زمینه درخواست، جلسه یا برنامه را فراهم میکند. کتابخانه struts-logic به شما امکان میدهد منطق اجرایی را با استفاده از تگها وارد کنید. هیچیک از این کتابخانهها ضروری نیستند. همانطور که دیدیم، یک صفحه JSP میتواند:
- استخراج اشیاء از درخواست (request.getAttribute(...))، جلسه (session.getAttribute(...)) یا زمینهٔ برنامه
- شامل کردن عناصر پویا در کد HTML با استفاده از متغیرها <%= variable %>
- حاوی کد جاوا <% کد جاوا %>
گنجاندن کد جاوا در صفحات JSP برای هر کسی که میخواهد جداسازی دقیقی بین منطق برنامه (کد جاوا) و ارائه (استفاده از تگها) حفظ کند، منبع سرخوردگی است. بنابراین، کتابخانههای تگ برای چنین کاربرانی توسعه داده شدهاند.
ما به همان شیوهای که برای نمای formulaire.jsp پیش رفتیم، عمل خواهیم کرد و هر یک از تگهای موجود در کد confirmation.jsp را توضیح میدهیم، اگر قبلاً در نمای formulaire.jsp با آنها مواجه نشده باشیم. ابتدا توجه داشته باشید که صفحه با اعلام سه کتابخانه تگ که استفاده خواهد کرد، آغاز میشود:
<%@ taglib uri="/WEB-INF/struts-bean.tld" prefix="bean" %>
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<%@ taglib uri="/WEB-INF/struts-logic.tld" prefix="logic" %>
همچنین شایان ذکر است که این سه کتابخانه باید در فایل web.xml برنامه اعلام شوند. اکنون به برچسبهای سند formulaire.jsp میپردازیم:
یک مقدار را به جریان فعلی HTML مینویسد. تگ bean:write از ویژگیهای زیر پشتیبانی میکند: name: نام شیء مورد استفاده دامنه (درخواست، جلسه، زمینه) برای جستجو این شیء property: فیلدی از شیء مشخصشده با نام که ویژگی آن باید نوشته شود. این فیلد میتواند شیئی از هر نوعی باشد. متد toString از آن شیء استفاده خواهد شد. در اینجا، مقدار فیلد «opt» از dynaFormulaire نوشته میشود. نتیجه یا «yes» خواهد بود اگر کاربر دکمه رادیویی با مقدار ویژگی «value="yes"» را علامت زده باشد، یا «no» اگر دکمه رادیویی با مقدار ویژگی «value="no"» را علامت زده باشد. |
مقدار فیلد chk1 را از dynaFormulaire مینویسد. مقدار آن یا «on» خواهد بود اگر کاربر تیک کادر را زده باشد، و در غیر این صورت «off». همین امر برای chk2 و chk3 نیز صدق میکند. |
مقدار فیلد champSaisie را از dynaFormulaire مینویسد، یعنی متنی که کاربر در آن فیلد وارد کرده است. همین امر در مورد mdp، boiteSaisie نیز صدق میکند. |
مقدار فیلد کادر ترکیبی را روی dynaFormulaire تنظیم میکند. این مقدار، ویژگی «value» عنصر <option> انتخابشده توسط کاربر خواهد بود. |
مقدار فیلد listeSimple را روی dynaFormulaire تنظیم میکند. این مقدار در صورتی که کاربر یک گزینه را انتخاب کرده باشد، بهعنوان ویژگی «value» عنصر <option> در نظر گرفته میشود. در غیر این صورت، یک رشتهٔ خالی خواهد بود. |
در اینجا، ما تگهای منطقی را معرفی میکنیم. ما با یک لیست چندگزینهای سروکار داریم. مقدار فیلد listeMultiple از شی dynaFormulaire یک آرایه از رشتهها است. در جاوا، ما یک حلقه مینویسیم. تگ `logic:iterate` به ما امکان میدهد همین حلقه را بدون نوشتن هیچ کد جاوا اجرا کنیم. در این مثال، تگ `logic:iterate` دارای ویژگیهای زیر است: name="dynaFormulaire": نام ابجکتی که باید استفاده شود property="listeMultiple": نام خاصیت در شیء مشخصشده توسط name که شامل مجموعهای است که در حلقه روی آن تکرار میشود. در اینجا، این مجموعه آرایه مقادیر انتخابشده در listeMultiple است. این آرایه ممکن است خالی باشد. id="choix": شناسهای که عنصر فعلی آرایه را در هر تکرار حلقه مشخص میکند. در طول تکرار اول، 'choix' نمایانگر 'listeMultiple[0]' خواهد بود؛ در تکرار دوم، 'listeMultiple[1]'؛ و به همین ترتیب. indexID="index": یک شناسهای که نمایه عنصر فعلی در آرایه را در هر تکرار حلقه مشخص میکند. در طول اولین تکرار، `index` مقدار 0 را خواهد داشت؛ در طول دومین تکرار، مقدار 1؛ و به همین ترتیب. کد HTML که بین تگهای <logic:iterate ...> و </logic:iterate> قرار دارد، برای هر عنصر در مجموعهای که با جفت (name,property) مشخص شده است، تکرار میشود. بخش پویا این کد به شرح زیر است:
بر اساس آنچه قبلاً گفته شد، در تکرار شماره i (i ≥ 0)، کد تولید شده HTML معادل کد زیر است: |
یک لینک را نسبت به زمینهٔ برنامه تولید میکند، به این معنی که نیازی نیست زمینه را بدانید. کد HTML تولیدشده توسط این تگ به شرح زیر است: |
6.5. کلاسهای جاوا
فایل پیکربندی struts-config.xml به دو کلاس جاوا ارجاع میدهد:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
...
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
کلاس DynaFormulaire کلاسی است که مقادیر را از نما شماره ۱، formulaire.jsp، در خود نگه میدارد. کلاس InitFormulaireAction کلاسی است که مقادیر ارسالشده از طریق دکمه [Envoyer] در formulaire.jsp را پردازش میکند.
6.5.1. کلاس DynaFormulaire
برای نگهداری مقادیر یک فرم، یک شی از نوع DynaActionForm کافی است، مگر اینکه نیاز باشد یکی از متدهای reset یا validate این کلاس را بازنویسی کنید. در اینجا، متد validate نیازی به بازنویسی ندارد، زیرا هیچ اعتبارسنجی دادهای انجام نمیشود. با این حال، متد reset باید بازنویسی شود. این به این دلیل است که فیلدهای شیء **DynaFormulaire** مقادیر خود را از فرم ارسالشده توسط کلاینت وب دریافت میکنند. با این حال، برخی فیلدها ممکن است مقداری دریافت نکنند اگر در درخواست وجود نداشته باشند. این در موارد زیر اتفاق میافتد:
- یک خانه تیک که توسط کاربر تیکخورده نشده است
- یک فهرست شامل بیش از یک مورد، یا هیچ گزینهای انتخاب نشده است
برای فرمهایی که حاوی این نوع مؤلفه هستند، روش ریست باید
- میدان مرتبط با چکباکس را روی مقدار «off» تنظیم کنید
- میدان مرتبط با یک لیست تکانتخابی را روی رشتهٔ خالی تنظیم کند
- یک آرایه رشتهای با اندازه صفر را به فیلد مرتبط با یک لیست چندگزینهای اختصاص دهد
بنابراین، اگر این فیلدها از پرسوجو (query) مقداری دریافت نکنند، مقداری را که توسط متد ریست (reset) تعیین شده است حفظ میکنند، که با وضعیت این کامپوننت در فرم ارسالشده توسط کاربر مطابقت دارد (تیکخورده نبودن چکباکس، عدم انتخاب هیچ موردی در لیست).
کد کلاس DynaFormulaire، کلاسی مشتقشده از DynaActionForm، به شرح زیر است:
package istia.st.struts.formulaire;
import org.apache.struts.action.DynaActionForm;
import org.apache.struts.action.ActionMapping;
import javax.servlet.http.HttpServletRequest;
public class DynaFormulaire extends DynaActionForm {
public void reset(ActionMapping mapping, HttpServletRequest request){
// بازنشانی چکباکسها – مقدار روی 'off' تنظیم میشود
set("chk1","off");
set("chk2","off");
set("chk2","off");
// بازنشانی listeSimple – رشتهٔ خالی
set("listeSimple","");
// بازنشانی listeMultiple – آرایه خالی
set("listeMultiple",new String[]{});
}
}
6.5.2. کلاس InitFormulaireAction
کلاس InitFormulaireAction در فایل struts-config.xml با عمل /init مرتبط است:
<action
path="/init"
name="dynaFormulaire"
validate="false"
scope="session"
type="istia.st.struts.formulaire.InitFormulaireAction"
>
<forward name="afficherFormulaire" path="/vues/formulaire.jsp"/>
</action>
عمل /init تنها یک بار در هنگام ایجاد اولیهٔ شیء DynaFormulaire استفاده میشود. هدف آن پر کردن سه لیست در کادر ترکیبی است: listeSimple و listeMultiple. این محتوا در قالب سه آرایه ارائه میشود که از ویژگیهای شیء dynaFormulaire هستند:
<form-bean name="dynaFormulaire" type="istia.st.struts.formulaire.DynaFormulaire">
<form-property name="opt" type="java.lang.String" initial="non"/>
...
<form-property name="valeursCombo" type="java.lang.String[]" />
<form-property name="valeursListeSimple" type="java.lang.String[]" />
<form-property name="valeursListeMultiple" type="java.lang.String[]"/>
</form-bean>
به محض اینکه آرایههای valeursCombo، valeursListeSimple و valeursListeMultiple توسط InitFormulaireAction مقداردهی اولیه شوند، دیگر نیازی به مقداردهی مجدد آنها نخواهد بود. این به این دلیل است که شیء dynaFormulaire در جلسه قرار میگیرد و بنابراین در تمام چرخههای درخواست-پاسخ مقدار خود را حفظ میکند. به همین دلیل است که عمل /init تنها یک بار اجرا میشود. کد مربوط به InitFormulaireAction به شرح زیر است:
package istia.st.struts.formulaire;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
public class InitFormulaireAction
extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
// فرم را برای نمایش آماده میکند
//اطلاعات لازم برای فرم در بین آن قرار میگیرد
DynaFormulaire formulaire = (DynaFormulaire) form;
formulaire.set("valeursCombo", getValeurs(5, "combo"));
formulaire.set("valeursListeSimple", getValeurs(7, "simple"));
formulaire.set("valeursListeMultiple", getValeurs(10, "multiple"));
//کنترل بازگردانده میشود
return mapping.findForward("afficherFormulaire");
} //اجرا
// فهرست مقادیر کادر ترکیبی
private String[] getValeurs(int taille, String label) {
String[] valeurs = new String[taille];
for (int i = 0; i < taille; i++) {
valeurs[i] = label + i;
}
return valeurs;
}
}
- کلاس از کلاس Action ارث میبرد. این الزامی است.
- کنترلکننده Struts از یک شیء Action از طریق متد `execute` آن استفاده میکند. بنابراین این متد است که باید بازنویسی شود. این متد پارامترهای زیر را میپذیرد:
- ActionMapping نگاشت: ابجکتی که پیکربندی برنامه را در struts-config.xml نشان میدهد
- ActionForm form: فرم مرتبط با اکشن، در صورتی که در پیکربندی اکشن تعریف شده باشد (ویژگی 'name' اکشن).
- HttpServletRequest درخواست: درخواست مشتری
- HttpServletResponse: پاسخ به کلاینت
- کلاس InitFormulaireAction باید فرم dynaFormulaire را مقداردهی اولیه کند. این فرم به متد `execute` بهعنوان پارامتر ActionForm form ارسال میشود. توجه داشته باشید که dynaFormulaire از نوع DynaFormulaire است، کلاسی که از کلاس DynaActionForm مشتق شده است، و آن خود از کلاس ActionForm مشتق شده است.
- در متد `execute`، مقادیر با استفاده از متد `set` کلاس `DynaActionForm` به سه فیلد `valeursCombo`، `valeursListeSimple` و `valeursListeMultiple` اختصاص داده میشوند. این مقادیر به منظور سادگی، آرایههای دلخواهی هستند. توجه داشته باشید که متد `set` یک مقدار را به یک فیلد موجود اختصاص میدهد. از آن نمیتوان برای ایجاد فیلدهای جدید استفاده کرد. به همین دلیل است که تعریف سه فیلد valeursCombo، valeursListeSimple، ضروری است، valeursListeMultiple در تعریف شیء dynaFormulaire درون struts-config.xml.
- متد `execute` با بازگرداندن کلید نمایی که باید به کنترلکننده به عنوان پاسخ به کلاینت نمایش داده شود، تکمیل میشود. در اینجا، این کلید `afficherFormulaire` است که در فایل `struts-config.xml` با نمای `/vues/formulaire.jsp` مرتبط شده است.
6.6. استقرار
ساختار دایرکتوری برنامه به شرح زیر است:
![]() | ![]() |
![]() | ![]() |


به خاطر داشته باشید که فایل ApplicationResources.properties فوق مورد نیاز کتابخانه تگ struts-bean است. ما میدانیم که این فایل حاوی پیامهای برنامه است. این پیامها برای کتابخانه struts-bean قابل دسترسی هستند. در اینجا، برنامه ما هیچ پیامی را تعریف نمیکند. بنابراین، فایل ApplicationResources.properties وجود دارد اما خالی است.
6.7. نتیجهگیری
در این درس، ما به تفصیل نحوه مدیریت اجزای مختلف یک فرم HTML را توضیح دادیم. اکنون میتوانیم از فرمهای پیچیده در برنامههای Struts خود استفاده کنیم.






