Skip to content

3. پردازش فرم توسط کنترلر

اکنون می‌بینیم که کنترلر هنگام کلیک کاربر روی دکمه [Envoyer] در فرم، مقادیر فرم را چگونه پردازش می‌کند.

3.1. فایل struts-config.xml

فایل پیکربندی جدید struts-config.xml برای کنترلر Struts به شرح زیر است:

<?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="frmPersonne" 
            type="istia.st.struts.personne.FormulaireBean"
        />
    </form-beans>

    <action-mappings>
      <action
          path="/main"
          name="frmPersonne"
            scope="session"
            validate="true"
            input="/erreurs.do"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />
      <action
          path="/erreurs"
          parameter="/vues/erreurs.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />
      <action
          path="/reponse"
          parameter="/vues/reponse.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />
      <action
          path="/formulaire"
          parameter="/vues/formulaire.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />
    </action-mappings>

    <message-resources parameter="ressources.personneressources"/>    
</struts-config>

تغییرات را برجسته کرده‌ایم:

  • یک بخش <form-beans> ظاهر می‌شود. این بخش برای تعریف کلاس‌های مرتبط با هر یک از فرم‌های برنامه استفاده می‌شود. باید به تعداد فرم‌های مختلف در برنامه، تگ‌های <form-bean> وجود داشته باشد. در اینجا ما فقط یک فرم داریم، بنابراین تنها یک بخش <form-bean> وجود دارد. برای هر فرم، باید تعریف کنیم:
    • نام آن (ویژگی name)
    • نام کلاسی که از ActionForm مشتق شده و مسئول ذخیره مقادیر فرم است (ویژگی type)

این دو ویژگی نمی‌توانند دلخواه باشند. آن‌ها باید دقیقاً مشابه مواردی باشند که در تگ <html:form> کد HTML فرم استفاده شده‌اند. بیایید این را برای فرم (name, age) به یاد بیاوریم:

      <html:form action="/main" name="frmPersonne" type="istia.st.struts.personne.FormulaireBean">

این فرم باید به همان شیوه در فایل struts-config.html اعلام شود. این کاری است که در اینجا انجام می‌شود:

        <form-bean 
            name="frmPersonne" 
            type="istia.st.struts.personne.FormulaireBean"
        />
  • پیکربندی اکشن /main تغییر کرده است. این اکشن مسئول پردازش مقادیر فرم است. بنابراین باید اطلاعات مورد نیاز آن را در داخل فرم فراهم کنیم:
      <action
          path="/main"
          name="frmPersonne"
            scope="session"
            validate="true"
            input="/erreurs.do"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />

سرولِت /main یک فرم را پردازش خواهد کرد که باید برای آن نامی تعیین شود. ویژگی 'name' این کار را انجام می‌دهد. این نام باید به ویژگی 'name' یکی از بخش‌های <form-bean> اشاره کند، که در این مورد frmPersonne است.

ویژگی scope="session" نشان می‌دهد که مقادیر فرم باید در جلسه (session) ذخیره شوند. این کار همیشه ضروری نیست. با این حال، در این مورد ضروری است. در واقع، در ویوهای /reponse.do و /erreurs.do، لینک‌هایی وجود دارند که به فرم بازمی‌گردند. در هر دو مورد، ما می‌خواهیم فرم را با مقادیر وارد شده توسط کاربر در طول یک تبادل قبلی بین کلاینت و سرور نمایش دهیم. از این رو، نیاز به ذخیره فرم در جلسه (session) وجود دارد.

ویژگی validate مشخص می‌کند که آیا متد validate شیء **frmPersonne** باید فراخوانی شود یا خیر. این متد برای بررسی اعتبار داده‌های فرم استفاده می‌شود. در اینجا، ما مشخص می‌کنیم که داده‌ها باید بررسی شوند، که به این معنی است که باید یک متد validate در کلاس **FormulaireBean بنویسیم. متد validate** فرم قبل از فراخوانی servlet /main توسط کنترل‌کننده Struts فراخوانی می‌شود. این متد یک شیء از نوع ActionErrors را بازمی‌گرداند که معادل یک لیست خطا است. اگر این لیست وجود داشته باشد و خالی نباشد، کنترل‌کننده Struts در آنجا متوقف شده و نمایی را که توسط ویژگی input مشخص شده است به عنوان پاسخ ارسال می‌کند. ویو لیست ActionErrors را در درخواست دریافت می‌کند که می‌تواند با استفاده از تگ <html:errors> آن را نمایش دهد. در بالا، بیان می‌کنیم که در صورت وجود خطا، servlet /main باید ویوی /erreurs.do را بازگرداند. به یاد داشته باشید که این نما با URL /views/erreurs.reponse.jsp زیر مرتبط است:

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
        <html:errors/>
    <html:link page="/formulaire.do">
            Retour au formulaire
        </html:link>      
    </body>
</html>

ویو به درستی از تگ <html:errors> استفاده می‌کند که لیست خطاها را نمایش می‌دهد. این لیست خطاها شامل خود پیام‌های خطا نیست، بلکه شناسه‌های پیام‌هایی است که در فایلی که توسط تگ <message-resources> (توجه: «resources» با یک «s» واحد) ارجاع داده شده، موجود هستند:

    <message-resources parameter="ressources.personneressources"/>    

تگ زیر نشان می‌دهد که فایلی که حاوی پیام‌های مورد استفاده توسط برنامه است، در فایل WEB-INF/classes/resources/personneressources.properties قرار دارد:

Image

در این فایل چه چیزی قرار دارد؟ این یک فایل properties است که با کلاس **Properties در جاوا مطابقت دارد، یعنی مجموعه‌ای از خطوط کلید=مقدار**:

errors.header=<ul>
errors.footer=</ul>
personne.formulaire.nom.vide=<li>Vous devez indiquer un nom</li>
personne.formulaire.age.incorrect=<li>L'âge [{0}] est incorrect</li>

این فایل پیام حداقل دو عملکرد دارد:

  • این امکان را به شما می‌دهد که پیام‌های برنامه را بدون نیاز به کامپایل مجدد آن تغییر دهید
  • این امکان را برای بین‌المللی‌سازی برنامه‌های Struts فراهم می‌کند. شما می‌توانید چندین فایل منبعی، یکی برای هر زبان، ایجاد کنید. Struts به‌طور خودکار فایل پیام مناسب را استفاده خواهد کرد، مشروط بر اینکه قواعد نام‌گذاری خاصی رعایت شود.
  • اگر متد `validate` فرم یک لیست خالی از خطاها را بازگرداند، آنگاه کنترلر Struts متد `execute` سرولتی به نام ForwardAction را فراخوانی می‌کند. در اینجا مهم است که درک کنیم وقتی متد `execute` سرویس‌لت اجرا می‌شود، به این معناست که داده‌های فرم معتبر تشخیص داده شده است (البته به شرطی که از طریق `validate="true"` بررسی شده باشد). این در داخل متد `execute` سرویس‌لت مرتبط با اکشن است که توسعه‌دهنده در واقع فرم را پردازش می‌کند. در اینجا هسته اصلی پردازش (منطق کاربردی، استفاده از کلاس‌های کسب‌وکار و کلاس‌های دسترسی به داده) انجام می‌شود. در نهایت، این متد نتیجه‌ای از نوع ActionForward را بازمی‌گرداند که به سازنده (constructor) می‌گوید کدام نما باید به کلاینت بازگردانده شود. در اینجا از اکشن از پیش تعریف‌شده Struts با نام ForwardAction استفاده کرده‌ایم. متد `execute` آن به سادگی یک ActionForward را بازمی‌گرداند که به URL اشاره دارد که توسط ویژگی `parameter` مشخص شده است:
      <action
          path="/main"
          name="frmPersonne"
            validate="true"
            input="/erreurs.do"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />

بنابراین، اگر داده‌های فرم معتبر باشند، اکشن /main نمای /vues/main.html را که قبلاً از آن استفاده کرده‌ایم، بازمی‌گرداند.

3.2. کلاس جدید FormulaireBean

ما قبلاً نسخه اولیه کلاس FormulaireBean را ایجاد کرده‌ایم که مسئول ذخیره داده‌های (نام، سن) از فرم formulaire.personne.jsp است. این نسخه اعتبار داده‌ها را بررسی نمی‌کرد. اکنون باید این کار را انجام دهیم، زیرا در فایل struts-config.xml مشخص کرده‌ایم که داده‌های فرم باید قبل از ارسال به سرولت ForwardAction اعتبارسنجی شوند (validate="true"). کد کلاس به صورت زیر درمی‌آید:

package istia.st.struts.personne;

import javax.servlet.http.*;
import org.apache.struts.action.*;

public class FormulaireBean
  extends ActionForm {
   // name
  private String nom = null;
  public String getNom() {
    return nom;
  }

  public void setNom(String nom) {
    this.nom = nom;
  }

   // age
  private String age = null;
  public String getAge() {
    return age;
  }

  public void setAge(String age) {
    this.age = age;
  }

   // اعتبارسنجی
  public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
    // مدیریت خطا
    ActionErrors erreurs = new ActionErrors();
     // نام خانوادگی نباید خالی باشد
    if (nom == null || nom.trim().equals("")) {
      erreurs.add("nomvide", new ActionError("personne.formulaire.nom.vide"));
       // سن باید یک عدد صحیح مثبت باشد
    }
    if (age == null || age.trim().equals("")) {
      erreurs.add("agevide", new ActionError("personne.formulaire.age.vide"));
    }
    else {
      // سن باید یک عدد صحیح مثبت باشد
      if (!age.matches("^\\s*\\d+\\s*$")) {
        erreurs.add("ageincorrect", new ActionError("personne.formulaire.age.incorrect", age));
        // بازگرداندن فهرست خطاها
      }
    } //اگر
     // فهرست خطاها را بازمی‌گرداند
    return erreurs;
  }
}

ویژگی جدید در پیاده‌سازی متد validate نهفته است. این متد پس از آنکه کنترلر Struts مقادیر فیلدهای فرم با همان نام را به ویژگی‌های name و age کلاس اختصاص داد، فراخوانی می‌شود. این متد باید اعتبار ویژگی‌های name و age را بررسی کند. کد بالا نسبتاً ساده است و به راحتی قابل درک است:

  • یک لیست خطاهای خالی (ActionErrors errors) ایجاد می‌شود
  • میدان «name» بررسی می‌شود. اگر خالی باشد، یک خطا با استفاده از متد ActionErrors.add("key", ActionError) به لیست خطاها اضافه می‌شود.
  • اگر فیلد 'age' عدد صحیح نباشد نیز همین کار انجام می‌شود.
  • متد validate لیست خطاها (ActionErrors errors) را به کنترلر Struts بازمی‌گرداند. اگر errors برابر null باشد یا اگر erreurs.size() برابر 0 باشد، کنترلر فرض می‌کند که هیچ خطایی رخ نداده است. سپس متد `execute` کلاس Action مرتبط با اکشن (type="org.apache.struts.actions.ForwardAction") را فراخوانی می‌کند. در غیر این صورت، نمای مرتبط با مدیریت خطاهای فرم (input="/erreurs.do") را بازمی‌گرداند.

یک خطا از طریق ActionErrors.add("cléErreur", new ActionError("cléMessage"[,param0, param1, param2, param3])). پارامتر اول، «cléErreur»، برای شناسایی منحصربه‌فرد یک عنصر ActionError در لیست ActionErrors، درست مانند یک فرهنگ لغت، استفاده می‌شود. این مقدار می‌تواند هر ارزشی باشد. ActionError یک شیء است که با استفاده از سازنده‌اش ActionError به یک پیام خطا مرتبط می‌شود(رشته cléMessage[,String param0, String param1, String param2, String param3])، که در آن cléMessage شناسه پیامی است که با خطا مرتبط است و تا چهار پارامتر اختیاری دارد. شناسگر cléMessage تصادفی نیست. این یکی از شناسگرهای موجود در فایلی است که توسط تگ <message-resources> در فایل struts-config.xml مشخص شده است:

    <message-resources parameter="ressources.personneressources"/>    

شایان ذکر است که این فایل (در واقع WEB-INF/classes/resources/personneressources.properties) شامل کلیدهای زیر است:

errors.header=<ul>
errors.footer=</ul>
personne.formulaire.nom.vide=<li>Vous devez indiquer un nom</li>
personne.formulaire.age.incorrect=<li>L'âge [{0}] est incorrect</li>

می‌توان تأیید کرد که کلیدهای پیامی که توسط متد validate** کلاس **FormulaireBean** استفاده شده‌اند، واقعاً در فایل فوق وجود دارند. برچسب کلاس HTML برای هر پیام خطا استفاده شده است تا برچسب <html:errors> آن‌ها را به صورت یک لیست HTML نمایش دهد. ما دیدیم که شیء ActionError** را می‌توان نه تنها با کلید پیام بلکه با پارامترهای اضافی نیز ساخت:

public ActionError(String cléMessage[,String param0, String param1, String param2, String param3])

اگر یک ActionError با پارامترهای اضافی (حداکثر تا چهار پارامتر) ساخته شده باشد، این پارامترها در متن پیام از طریق notation {0} تا {3} قابل دسترسی هستند. بنابراین، متد validate کلاس FormulaireBean یک کلاس ActionError را با کلید personne.formulaire.age.incorrect و پارامتر اضافی param0 ایجاد می‌کند:

      erreurs.add("age", new ActionError("personne.formulaire.age.incorrect",age));

پیامی که با کلید personne.formulaire.age.incorrect در فایل .properties پیام‌ها مرتبط است، عبارت است از

personne.formulaire.age.incorrect=<li>L'âge [{0}] est incorrect</li>

{0} با مقدار سن جایگزین خواهد شد. در نهایت، پیام‌ها با کلیدهای errors.header و errors.footer به‌ترتیب قبل و بعد از فهرست خطاها نوشته خواهند شد. در اینجا از این دو کلید برای درج برچسب‌های HTML و استفاده می‌شود که باید برچسب‌های را احاطه کنند.

3.3. آزمایش‌های اعتبارسنجی فرم

اکنون آماده انجام تست‌های اعتبارسنجی فرم هستیم. در زیر یادآوری‌ای از محل قرارگیری اجزای مختلف برنامه آورده شده است:

les vues
les fichiers de configuration
le fichier des messages
les classes

3.3.1. آزمون ۱

بیایید تام‌کت را مجدداً راه‌اندازی کنیم تا فایل‌های پیکربندی جدید را بخواند، سپس http://localhost:8080/strutspersonne/formulaire.do را درخواست کنیم:

Image

توضیحات:

  • در struts-config.html، بخش زیر مورد بهره‌برداری قرار گرفت:
      <action
          path="/formulaire"
          parameter="/vues/formulaire.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />

اگر کد HTML را از صفحه دریافت‌شده مشاهده کنیم، می‌توانیم ببینیم که تگ <form> در صفحه به شرح زیر است:

      <form name="frmPersonne" method="post" action="/strutspersonne/main.do">

دکمه [Envoyer] که یک دکمه ارسال است، بنابراین داده‌های فرم را به URL /strutspersonne/main.do ارسال خواهد کرد.

3.3.2. آزمون ۲

بیایید از دکمه [Envoyer] استفاده کنیم و فیلدهای ورودی را خالی بگذاریم. پاسخ زیر را دریافت می‌کنیم:

Image

توضیح:

  • همان‌طور که در بالا ذکر شد، داده‌های فرم به URL /strutspersonne/main.do ارسال شد. سپس بخش‌های زیر از فایل struts-config.xml استفاده شدند:
        <form-bean 
            name="frmPersonne" 
            type="istia.st.struts.personne.FormulaireBean"
            scope="session"
        />
....
      <action
          path="/main"
          name="frmPersonne"
            validate="true"
            input="/erreurs.do"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />

اقدام /main اجرا شده است. این اقدام از فرم frmPersonne (name="frmPersonne") استفاده می‌کند. بنابراین کنترلر Struts در صورت لزوم یک شیء از کلاس FormulaireBean (نوع="istia.st.struts.personne.FormulaireBean" در تگ form-bean) را ایجاد کرده است. وی ویژگی‌های «name» و «age» این شیء را با فیلدهایی با همین نام از فرم HTML پر کرد:

          <table>
            <tr>
              <td>Nom</td>
            <td><html:text property="nom" size="20"/></td>
          </tr>
          <tr>
              <td>Age</td>
            <td><html:text property="age" size="3"/></td>
          </tr>
            <tr>
        </table>

پس از انجام این کار، کنترل‌کننده Struts متد validate از شیء **FormulaireBean را فراخوانی کرد، زیرا ویژگی validate از اکشن **/main** در فایل پیکربندی روی true** تنظیم شده است:

      <action
          path="/main"
          name="frmPersonne"
            validate="true"
            input="/erreurs.do"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />

متد validate کلاس FormulaireBean به شرح زیر است:

  //اعتبارسنجی
  public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
    // مدیریت خطا
    ActionErrors erreurs = new ActionErrors();
     //نام نباید خالی باشد
    if (nom == null || nom.trim().equals("")) {
      erreurs.add("nomvide", new ActionError("personne.formulaire.nom.vide"));
       // سن باید یک عدد صحیح مثبت باشد
    }
    if (age == null || age.trim().equals("")) {
      erreurs.add("agevide", new ActionError("personne.formulaire.age.vide"));
    }
    else {
      //سن باید یک عدد صحیح مثبت باشد
      if (!age.matches("^\\s*\\d+\\s*$")) {
        erreurs.add("ageincorrect", new ActionError("personne.formulaire.age.incorrect", age));
        //فهرست خطاها را بازمی‌گرداند
      }
    } //اگر
     // فهرست خطاها را بازمی‌گرداند
    return erreurs;
  }

از آنجایی که فیلدهای [nom] و [age] خالی بودند، متد validate فوق یک لیست شامل دو خطا تولید کرد که آن را به کنترلر Struts بازگرداند. از آنجا که خطاهایی وجود داشت، کنترلر سپس ویوی مرتبط با ویژگی input را به کلاینت بازگرداند. برای تعیین اینکه این نما کدام بود، از بخش زیر در فایل پیکربندی خود استفاده کرد:

      <action
          path="/erreurs"
          parameter="/vues/erreurs.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />

بنابراین، در نهایت، نمای /vues/erreurs.personne.jsp ارسال شد. این شامل کد زیر است:

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
        <html:errors/>
    <html:link page="/formulaire.do">
            Retour au formulaire
        </html:link>    
  </body>
</html>

تگ <html:errors> صرفاً فهرست پیام‌هایی را که توسط کنترل‌کننده Struts برای آن ارسال شده است، نمایش می‌دهد. این تگ از فایل پیام مشخص‌شده توسط تگ <message-resources> استفاده می‌کند:

    <message-resources parameter="ressources.personneressources"/>

این شامل کلیدها و پیام‌های زیر است:

personne.formulaire.nom.vide=<li>Vous devez indiquer un nom</li>
personne.formulaire.age.vide=<li>Vous devez indiquer un age</li>
personne.formulaire.age.incorrect=<li>L'âge [{0}] est incorrect</li>
errors.header=<ul>
errors.footer=</ul>
  • پیام مرتبط با کلید errors.header نوشته شده است
  • پیام‌های مرتبط با کلیدهای مختلف در فهرست دریافتی ActionErrors نوشته شده‌اند
  • پیام مرتبط با کلید errors.footer نوشته شده است

3.3.3. آزمون ۳

بیایید از لینک [Retour au formulaire] در صفحهٔ خطاها استفاده کنیم. به صفحهٔ زیر هدایت می‌شویم:

Image

توضیحات:

  • لینک [Retour au formulaire] دارای کد زیر است: HTML
    <a href="/strutspersonne/formulaire.do">Retour au formulaire</a>

کنترل‌کننده Struts از بخش زیر در فایل پیکربندی خود استفاده کرد:

      <action
          path="/formulaire"
          parameter="/vues/formulaire.personne.jsp"
          type="org.apache.struts.actions.ForwardAction"
      />

بنابراین نمای /views/formulaire.personne.jsp را بازگرداند.

3.3.4. آزمون ۴

ما فرم زیر را پر می‌کنیم و سپس روی دکمه [Envoyer] کلیک می‌کنیم:

Image

پاسخ زیر را دریافت می‌کنیم:

Image

توضیحات: این‌ها همانند آزمون شمارهٔ ۲ هستند.

3.3.5. آزمون ۵

ما از لینک [Retour au formulaire] بالا استفاده می‌کنیم. صفحه زیر را دریافت می‌کنیم:

Image

می‌توانیم ببینیم که فرم دقیقاً همان‌طور که ارسال کردیم، نمایش داده می‌شود.

توضیحات: این موارد همانند آزمون شمارهٔ ۳ هستند، با یک نکتهٔ اضافی:

  • فرم نمایش‌داده‌شده HTML دارای تگ‌های زیر است:
          <table>
            <tr>
              <td>Nom</td>
            <td><html:text property="nom" size="20"/></td>
          </tr>
          <tr>
              <td>Age</td>
            <td><html:text property="age" size="3"/></td>
          </tr>
            <tr>
        </table>

برچسب‌های <html:text> دو عملکرد دارند:

  • هنگامی که مقادیر فرم از سمت کلاینت به سرور ارسال می‌شوند، مقادیر فیلدهای ورودی فرم به فیلدهای با نام مشابه در شیء FormulaireBean اختصاص داده می‌شوند
  • هنگامی که سرور کد فرم HTML را برای نمایش به کلاینت ارسال می‌کند، ویژگی‌های مقدار (value) فیلدهای ورودی مرتبط با برچسب‌های <html:text> با مقادیر فیلدهای هم‌نام در شیء FormulaireBean مقداردهی اولیه می‌شوند.

در اینجا دو تبادل متفاوت بین کلاینت و سرور وجود دارد:

  • در مورد اول، کاربر فرم را تکمیل کرده و آن را برای سرور ارسال کرده است
  • در مورد دوم، کاربر از لینک [Retour au formulaire] برای بازگشت به فرم استفاده کرده است.

تنها راه برای نمایش مجدد فرم با مقادیر اصلی‌اش در تعامل دوم، ذخیره‌سازی آن مقادیر در جلسه (session) کلاینت است. این همان چیزی است که در بخش پیکربندی اقدام /main مشخص شده بود:

      <action
          path="/main"
          name="frmPersonne"
            scope="session"
            validate="true"
            input="/erreurs.do"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />

اگر ما scope="request" را تنظیم کرده بودیم، داده‌های فرم در جلسه (session) ذخیره نمی‌شد و در نتیجه نمی‌توانستیم مقادیر آن را در تبادل دوم بازیابی کنیم.

3.3.6. آزمون ۶

بیایید به فرم بازگردیم و این بار داده‌های معتبری وارد کنیم:

Image

بیایید فرم را ارسال کنیم. نتیجه زیر را دریافت می‌کنیم:

Image

توضیح:

  • زیرا دکمه [Envoyer] مقادیر فرم را به URL /strutspersonne/main.do ارسال می‌کند، ما همان توضیحات را مانند تست شماره ۲ می‌یابیم تا زمانی که نتیجه ActionErrors از متد validate کلاس FormulaireBean به کنترلر Struts بازگردانده می‌شود. اما در اینجا، این لیست خالی است. سپس کنترلر از بخشی جدید از پیکربندی برای اکشن /main استفاده می‌کند:
      <action
          path="/main"
          name="frmPersonne"
            scope="session"
            validate="true"
            input="/erreurs.do"
          parameter="/vues/main.html"
          type="org.apache.struts.actions.ForwardAction"
      />

کنترل‌کننده Struts، در صورت لزوم، یک شیء از نوع مشخص‌شده توسط صفت type ایجاد می‌کند. متد execute این کلاس فراخوانی می‌شود و باید یک شیء از نوع ActionForward بازگرداند که نمایی را مشخص می‌کند که کنترل‌کننده باید به‌عنوان پاسخ برای کلاینت ارسال کند. در اینجا، ویژگی type به کلاس از پیش تعریف‌شده **ForwardAction اشاره دارد. متد execute** این کلاس هیچ کاری انجام نمی‌دهد و صرفاً یک شیء ActionForward را که به ویوی تعریف‌شده توسط ویژگی parameter اشاره دارد، در این مورد ویوی **/vues/main.html**، برمی‌گرداند. این دقیقاً همان ویویی است که کنترلر بازگردانده است.

3.3.7. آزمون ۷

ما دوباره نمای /formulaire.do را درخواست می‌کنیم:

Image

ما فرم را دقیقاً همان‌طور که ارسال کردیم، می‌بینیم. توضیحات قبلاً داده شده است. با تنظیم پیکربندی (scope="session")، ما اطمینان حاصل کرده‌ایم که فرم در جلسه (session) باقی می‌ماند. بنابراین مقادیر آن در طول تبادل‌های کلاینت-سرور حفظ می‌شوند.

ما تقریباً کارمان تمام شده است. هنوز باید یک اکشن مناسب برای زمانی که داده‌های فرم معتبر هستند ایجاد کنیم. فعلاً، برای ساده‌سازی نمایش خود از اکشن از پیش تعریف‌شده ForwardAction استفاده کرده‌ایم.

3.4. پیکربندی جدید برای اکشن /main

ما فایل پیکربندی فعلی struts-config.xml را تغییر نمی‌دهیم، به جز اصلاح بخش /main آن به شرح زیر:

      <action
          path="/main"
          name="frmPersonne"
            scope="session"
            validate="true"
            input="/erreurs.do"
          type="istia.st.struts.personne.FormulaireAction"
      >
            <forward name="reponse" path="/reponse.do"/>
        </action>

ویژگی «type» اکنون به کلاس دیگری به نام FormulaireAction اشاره دارد که باید آن را ایجاد کنیم. متد «execute» این کلاس در صورتی که داده‌های فرم frmPersonne معتبر باشند، اجرا خواهد شد. ما مشخص کرده‌ایم که متد **execute وظیفه مورد نیاز خود را انجام می‌دهد و یک شیء از نوع **ActionForward را بازمی‌گرداند که نمایی را که کنترلر باید به کلاینت بازگرداند، مشخص می‌کند. اغلب چندین نمای ممکن بسته به نتیجه پردازش فرم وجود دارد. فهرست نماهای مختلف ممکن در داخل تگ‌های <forward> که در تگ <action> گنجانده شده‌اند، مشخص می‌شود. نحو چنین تگی به شرح زیر است:

            <forward name="clé" path="/vue" />
clé
هر نامی که یک نما را به‌طور منحصربه‌فرد شناسایی می‌کند
vue
کلاس URL نمای مرتبط با کلید

3.5. کلاس FormulaireAction

نوشتن کلاس FormulaireAction اساساً شامل نوشتن متد **execute** آن است:

package istia.st.struts.personne;

import org.apache.struts.action.Action;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import javax.servlet.ServletException;

public class FormulaireAction extends Action {

  public ActionForward execute(ActionMapping mapping, ActionForm form,
                               HttpServletRequest request, HttpServletResponse response)
                                         throws IOException,ServletException {

     //فرم معتبر است؛ در غیر این صورت، به این نقطه نمی‌رسیدیم
    FormulaireBean formulaire=(FormulaireBean)form;
    request.setAttribute("nom",formulaire.getNom());
    request.setAttribute("age",formulaire.getAge());
    return mapping.findForward("reponse");
  }//اجرا می‌کند
}

متد execute چهار پارامتر می‌گیرد:

  1. نقشه‌برداری ActionMapping: یک شیء «تصویر» از پیکربندی عملی که در حال اجراست؛ بنابراین در این مورد، تصویری با پیکربندی زیر:
      <action
          path="/main"
          name="frmPersonne"
            validate="true"
            input="/erreurs.do"
          type="istia.st.struts.personne.FormulaireAction"
      >
            <forward name="reponse" path="/reponse.do"/>
        </action>

این دسترسی را به اکشن برای دسترسی به کلیدهای مرتبط با ویوها می‌دهد، که پس از اتمام اکشن می‌توانند به کلاینت بازگردانده شوند. متد **execute** باید یکی از این کلیدها را بازگرداند.

  1. ActionForm فرم: شیء bean حاوی مقادیر فرم است که توسط اکشن جاری استفاده می‌شود. در اینجا، این شیء frmPersonne از نوع FormulaireBean است. این دسترسی را به اکشن برای مقادیر فرم می‌دهد.
  2. درخواست HttpServletRequest: درخواست کلاینت که ممکن است توسط سرولت‌های مختلف غنی‌سازی شده باشد. بنابراین، اکشن به تمام پارامترهای درخواست اولیه (request.getParameter) و همچنین به تمام ویژگی‌های اضافه شده به آن درخواست اولیه دسترسی دارد (request.getAttribute). در مثال ما، متد `execute` با افزودن نام و سن، درخواست را غنی می‌کند. این کار در اینجا کاملاً غیرضروری است، زیرا این دو مقدار از قبل وجود دارند، اما به صورت پارامتر به جای ویژگی‌ها. این کد برای اهداف نمایشی در اینجا گنجانده شده است.
  3. پاسخ HttpServletResponse: پاسخی که به کلاینت ارسال خواهد شد. اکشن می‌تواند این پاسخ را غنی‌سازی کند. در اینجا این کار را انجام نمی‌دهد.

در اینجا، با یک مورد خاص سروکار داریم. متد execute عملاً کاری برای انجام دادن ندارد. این متد صرفاً باید نشان دهد که نمای بعدی، نمای **/reponse.do** است و در درخواست مشخص کند که این نما اطلاعات نام و سن را که برای نمایش الزامی است، دریافت خواهد کرد. این کار را با استفاده از متد **findForward** از کلاس ActionMapping انجام می‌دهد که یکی از کلیدهای موجود در تگ‌های forward در پیکربندی اکشن را به عنوان پارامتر می‌گیرد. در اینجا تنها یک تگ از این دست وجود دارد:

            <forward name="reponse" path="/reponse.do"/>

بنابراین متد execute ما یک **ActionForward** را با کلید «response» بازمی‌گرداند تا نشان دهد که نمای **/reponse.do** باید ارسال شود.

3.6. آزمایش FormulaireAction

ما کلاس قبلی را با استفاده از JBuilder کامپایل می‌کنیم و فایل .class تولیدشده را در WEB-INF/classes قرار می‌دهیم:

Image

ما نمای /vues/reponse.personne.jsp را تغییر می‌دهیم:

<%
     // بازیابی نام و داده‌های سن
  String nom=(String)request.getAttribute("nom");
  String age=(String)request.getAttribute("age"); 
%>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Personne - réponse</h2>
    <hr>
    <table>
        <tr>
          <td>Nom</td>
        <td><%= nom %>
      </tr>
        <tr>
          <td>Age</td>
        <td><%= age %>
      </tr>
    </table>      
    <html:link page="/formulaire.do">
            Retour au formulaire
        </html:link>    
  </body>
</html>

ویو نام و اطلاعات سن را از ویژگی‌های درخواستی که دریافت می‌کند، بازیابی می‌کند. ما فرم را از URL http://localhost:8080/strutspersonne/formulaire.do درخواست می‌کنیم و سپس آن را پر می‌کنیم:

Image

روی دکمه [Envoyer] کلیک می‌کنیم و پاسخ زیر را دریافت می‌کنیم:

Image

توضیحات:

  • برای شروع فرایند به توضیحات ارائه‌شده برای آزمون شمارهٔ ۲ مراجعه خواهیم کرد. بیایید پیکربندی عمل /main را به یاد بیاوریم:
      <action
          path="/main"
          name="frmPersonne"
            scope="session"
            validate="true"
            input="/erreurs.do"
          type="istia.st.struts.personne.FormulaireAction"
      >
            <forward name="reponse" path="/reponse.do"/>
        </action>
  • پس از ارسال فرم به کنترلر در URL /main.do، کنترلر یک شیء از نوع FormulaireBean به نام frmPersonne ایجاد یا مجدداً استفاده کرد و آن را با مقادیر فرم پر کرد
  • متد validate شیء frmPersonne فراخوانی شد. از آنجا که داده‌ها معتبر بودند، متد validate یک لیست خالی ActionErrors را بازگرداند.
  • یک شیء FormulaireAction ایجاد یا بازیافت شد و متد `execute` آن فراخوانی شد. این متد یک شیء ActionForward با کلید "reponse" را بازگرداند.
  • سپس کنترلر نمای مرتبط با کلید «reponse»، c.a.d. /reponse.do و در نتیجه /views/reponse.personne.jsp را ارسال کرد.
  • ویو reponse.personne.jsp با مقادیری که توسط متد `execute` شیء FormulaireAction در درخواست تنظیم شده بود، نمایش داده شد.

3.7. نتیجه‌گیری

ما یک برنامه کامل و در عین حال ساده ساخته‌ایم. هنگام پیاده‌سازی واقعی آن با Struts، Tomcat و JBuilder، فرصت‌های متعددی برای اشتباه کردن وجود دارد، به‌ویژه در فایل‌های پیکربندی برنامه مانند XML. در نگاه اول، ممکن است ساخت این برنامه بدون Struts، با استفاده از یک servlet و صفحات JSP، ساده‌تر به نظر برسد. برای یک مبتدی، این احتمالاً درست است. با این حال، با کسب تجربه، توسعه با Struts آسان‌تر می‌شود. بسیاری از شرکت‌ها به دلایل زیر، روش‌شناسی Struts را برای توسعه وب خود الزامی می‌کنند:

  • استروتس از مدل MVC پیروی می‌کند
  • وقتی همه توسعه‌دهندگان به یک روش کار می‌کنند، نگهداری برنامه آسان‌تر می‌شود زیرا یک معماری استاندارد دارند.