Skip to content

2. تطبيق strutspersonne

لقد قمنا بتنفيذ تطبيق "person" باستخدام الطريقة التقليدية: سيرفلتس وصفحات JSP. نقترح الآن تقديم Struts باستخدام هذا التطبيق نفسه.

2.1. كيف يعمل التطبيق

دعونا نستعرض كيفية عمل تطبيق "person" الذي قمنا بتطويره. يتكون من:

  • Servlet رئيسي. يتولى هذا معالجة جميع منطق التطبيق.
  • ثلاث صفحات JSP: formulaire.personne.jsp و reponse.personne.jsp و erreurs.personne.jsp

يعمل التطبيق على النحو التالي. يمكن الوصول إليه عبر عنوان URL http://localhost:8080/personne/main. عند هذا العنوان، يتم عرض نموذج مقدم من صفحة formulaire.personne.jsp:

Image

يقوم المستخدم بملء النموذج والنقر على زر [Submit]. زر [Reset] هو زر إعادة تعيين، مما يعني أنه يعيد المستند إلى الحالة التي تم استلامه بها. زر [Delete] هو زر قياسي. يجب على المستخدم إدخال اسم وعمر صالحين. إذا لم يكن الأمر كذلك، يتم إرسال صفحة خطأ إليه عبر صفحة JSP erreurs.personne.jsp. فيما يلي بعض الأمثلة:

التبادل رقم 1

الطلب
الرد

إذا اتبعت رابط [العودة إلى النموذج]، فستجد النموذج في الحالة التي تركته عليها:

التبادل رقم 2

طلب
الرد

إذا أرسل المستخدم بيانات صالحة، فإن التطبيق يرسل استجابة عبر صفحة JSP reponse.personne.jsp.

التبادل رقم 1

الطلب
الرد

إذا اتبعت رابط [العودة إلى النموذج]، فستجد النموذج في الحالة التي تركته عليها:

التبادل رقم 2

الطلب
الرد

2.2. بنية Struts للتطبيق

سنعتمد بنية Struts التالية:

  • ستكون هناك ثلاث طرق للعرض
  • سيكون وحدة التحكم هي تلك التي يوفرها Struts
  • FormBean هي الفئة المسؤولة عن تخزين القيم من النموذج الذي يعرضه العرض form.person.jsp
  • FormAction هي الفئة المسؤولة عن معالجة قيم FormBean وتحديد صفحة الاستجابة المراد إرسالها:
    • عرض errors.person.jsp إذا كانت بيانات النموذج غير صحيحة
    • عرض reponse.personne.jsp في الحالات الأخرى

بالنسبة للمطور، تتمثل المهمة في كتابة الكود:

  • العروض الثلاثة
  • FormBean المرتبط بالنموذج
  • فئة FormAction المسؤولة عن معالجة النموذج

2.3. تجميع الفئات المطلوبة لتطبيق Struts

لتجميع الفئات المطلوبة لتطبيقنا، سنستخدم JBuilder. يعمل JBuilder مع JDK لا يحتوي على الفئات المطلوبة لتطبيقات Struts. يمكننا تكوين JBuilder على النحو التالي:

  • أدوات / تكوين JDKs

Image

  • استخدم زر [إضافة] لإضافة ملفات .jar التي يوفرها Struts إلى أرشيفات فئات JBuilder. إذا كنت قد قمت باستخراج أرشيف Struts إلى القرص الخاص بك، فيمكنك إضافة جميع ملفات .jar من المجلد <struts>/lib إلى JBuilder:

Image

يمكنك إضافة جميع ملفات .jar المذكورة أعلاه إلى أرشيفات JBuilder. وقد رأينا بالفعل أن Tomcat يحتاج أيضًا إلى الوصول إلى أرشيفات Struts. بالنسبة لـ Tomcat 4.x، يمكنك وضع ملفات .jar الخاصة بـ Struts في <tomcat4>\common\lib. بالنسبة لـ Tomcat 5.x، يمكنك وضعها في <tomcat5>\shared\lib. يمكنك بعد ذلك تكوين JBuilder لتحديد موقع ملفات .jar الخاصة بـ Struts في نفس موقع Tomcat. هذا ما تم فعله في لقطة الشاشة التي تظهر ملفات .jar الخاصة بـ JBuilder المذكورة سابقًا. تم أخذها من <tomcat5>\shared\lib.

لذا، إذا أبلغ JBuilder أنه لا يمكنه العثور على فئة Struts أثناء ترجمة فئة ما، فتحقق من أمرين:

  • تهجئة الفئة
  • ملفات .jar المستخدمة بواسطة JBuilder. يجب تضمين جميع ملفات Struts .jar.

2.4. طرق عرض تطبيق strutspersonne

طرق العرض الثلاثة للتطبيق هي كما يلي:

  • form.person.jsp: يعرض النموذج لإدخال اسم الشخص وعمره
  • reponse.personne.jsp: يعرض القيم التي تم إدخالها إذا كانت صالحة
  • errors.person.jsp: يعرض أي أخطاء

2.4.1. طريقة العرض errors.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>

هناك ميزتان جديدتان في هذا الكود:

  1. وجود علامات <html:XX/>، وهي ليست علامات HTML. يمكنك إنشاء مكتبات لعلامات JSP التي يتم تحويلها إلى كود Java عند تحويل صفحة JSP إلى سيرفلت.
  2. يجب أن تعلن صفحة JSP عن مكتبات العلامات التي تستخدمها. وهي تفعل ذلك هنا بالسطر
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>

يقدم هذا السطر معلومتين:

  • uri: موقع الملف الذي يحكم قواعد استخدام المكتبة. يتم تضمين ملف struts-html.tld في توزيع Struts. في المثال أعلاه، تم وضعه في مجلد WEB-INF.
  • prefix: المعرف المستخدم في الكود لإضافة بادئة لعلامات المكتبة. وهذا يمنع تعارضات التسمية التي قد تنشأ عند استخدام مكتبات علامات متعددة في وقت واحد. من الممكن العثور على علامتين تحملان نفس الاسم في مكتبتين مختلفتين. ومن خلال إعطاء كل مكتبة بادئة مختلفة، يتم التخلص من أي غموض.
  • تعرض علامة <html:errors> قائمة الأخطاء التي يرسلها وحدة التحكم Struts إليها.
  • تقوم علامة <html:link> بإنشاء رابط يشير إلى /C/page حيث
    • حيث C هو سياق التطبيق
    • page هو عنوان URL المحدد في سمة page للعلامة

ال

    <html:link page="/formulaire.do">
            Retour au formulaire
        </html:link>

سيؤدي إلى إنشاء كود HTML التالي:

<a href="/C/formulaire.do">Retour au formulaire</a>

حيث C هو سياق التطبيق

2.4.2. اختبار عرض errors.person.jsp

  • يتم وضع ملف errors.person.jsp في مجلد views الخاص بتطبيق strutspersonne:

Image

  • يتم أخذ ملف struts-html.tld من توزيع Struts (<struts>/lib) ووضعه في WEB-INF:

Image

  • يتم تعديل ملف 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>
    <action-mappings>
      <action
          path="/main"
          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-mappings>
</struts-config>

نقوم بإنشاء عنوان URL جديد هو /errors في ملف التكوين ليتولى معالجته وحدة التحكم Struts. وسيتم إعادة توجيه عنوان URL /errors.do إلى صفحة العرض /views/errors.person.jsp. ويتم وضع ملف struts-config.xml في مجلد WEB-INF.

  • نقوم بإعادة تشغيل Tomcat حتى يتم أخذ ملف struts-config.xml الجديد في الاعتبار، ثم نطلب عنوان URL http://localhost:8080/strutspersonne/erreurs.do:

Image

لم تنتج العلامة <html:errors/> أي شيء. هذا أمر طبيعي؛ لم تقم ForwardAction بإنشاء قائمة الأخطاء التي تتوقعها العلامة. ومع ذلك، تظهر الاستجابة أعلاه أن عرض JSP الخاص بنا صحيح من الناحية النحوية على الأقل؛ وإلا لكنا قد تلقينا صفحة خطأ. دعونا نتحقق من كود HTML الذي تلقاه المتصفح (عرض/المصدر):

<html>
    <head>
      <title>Personne - erreurs</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>        
    <a href="/strutspersonne/formulaire.do">Retour au formulaire</a>    
  </body>
</html>

لاحظ الرابط الذي تم إنشاؤه بواسطة علامة <html:link>. تم تضمين سياق /strutspersonne تلقائيًا في الرابط. وهذا يسمح بنقل التطبيق من سياق إلى آخر (على سبيل المثال، تغيير الأجهزة) دون الحاجة إلى تغيير الروابط التي تم إنشاؤها بواسطة <html:link>.

2.4.3. طريقة العرض reponse.personne.jsp

هذه العرض، الذي يؤكد القيم التي تم إدخالها في النموذج، هو كما يلي:

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

<%
    // on récupère les données nom, age
  //String nom=(String)request.getAttribute("nom");
  String nom="jean";

  //String age=(String)request.getAttribute("age"); 
  String age="24"; 
%>

<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>      
    <br>
    <html:link page="/formulaire.do">
            Retour au formulaire
        </html:link>    
  </body>
</html>

تعرض الصفحة معلومتين، هما [name] و[age]، اللتين سيتم تمريرهما إليها من وحدة التحكم ضمن كائن الطلب المُعرَّف مسبقًا. هنا، نجري اختبارًا لن تتمكن فيه وحدة التحكم من تعيين قيم [name] و[age]. ولذلك، نقوم بتهيئة هاتين المعلومتين بقيم عشوائية. بالإضافة إلى ذلك، يتم هنا أيضًا إنشاء الرابط للعودة إلى النموذج باستخدام علامة <html:link>.

2.4.4. اختبار عرض reponse.personne.jsp

  • يوجد ملف reponse.personne.jsp في مجلد views الخاص بتطبيق strutspersonne:

Image

  • يتم تعديل ملف 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>
    <action-mappings>
      <action
          path="/main"
          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-mappings>
</struts-config>

نقوم بإنشاء عنوان URL جديد /reponse في ملف التكوين ليتم معالجته بواسطة وحدة التحكم Struts. سيتم إعادة توجيه عنوان URL /reponse.do إلى العرض /vues/reponse.personne.jsp. يتم وضع ملف struts-config.xml في مجلد WEB-INF.

  • نقوم بإعادة تشغيل Tomcat حتى يتم أخذ ملف struts-config.xml الجديد في الاعتبار، ثم نطلب عنوان URL http://localhost:8080/strutspersonne/erreurs.do:

Image

نحصل على النتيجة التي توقعناها بالضبط.

2.4.5. طريقة العرض formulaire.personne.jsp

تعرض هذه العرض النموذج الخاص بإدخال اسم المستخدم وعمره. وفيما يلي كود JSP الخاص بها:

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

<html>
    <meta http-equiv="pragma" content="no-cache"> 
    <head>
      <title>Personne - formulaire</title>
    <script language="javascript">
        function effacer(){
          with(document.frmPersonne){
            nom.value="";
          age.value="";
        }
      }
    </script>
  </head>

  <body>
      <center>
        <h2>Personne - formulaire</h2>
      <hr>
      <html:form action="/main" name="frmPersonne" type="istia.st.struts.personne.FormulaireBean">
          <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>
        <table>
            <tr>
              <td><html:submit value="Envoyer"/></td>
            <td><html:reset value="Rétablir"/></td>
            <td><html:button property="btnEffacer" value="Effacer" onclick="effacer()"/></td>
          </tr>
        </table>
      </html:form>
    </center>
  </body>
</html>

نرى مكتبة العلامات struts-html.tld مستخدمة في عرض الأخطاء. تظهر علامات جديدة:

html:form
تُستخدم لإنشاء علامة HTML <form> ولتزويد وحدة التحكم بالمعلومات التي ستعالج هذا النموذج:
action
عنوان URL الذي سيتم إرسال قيم النموذج إليه
name
اسم نموذج HTML. وهو أيضًا اسم الكائن الذي سيخزن قيم النموذج
النوع
اسم الفئة التي يجب إنشاء مثيل لها للحصول على bean تخزين النموذج
لاحظ أن الطريقة المستخدمة لإرسال معلمات النموذج (GET/POST) إلى وحدة التحكم غير محددة. يمكن القيام بذلك باستخدام سمة method. إذا كانت هذه السمة مفقودة، يتم استخدام طريقة POST بشكل افتراضي.
html:text
تُستخدم لإنشاء العلامة <input type="text" value="...">:
الخاصية
اسم الحقل في حبة النموذج الذي سيتم ربطه بحقل الإدخال. عند إرسال النموذج إلى الخادم (العميل -> الخادم)، سيأخذ حقل الحبة قيمة حقل الإدخال. عند عرض النموذج (الخادم -> العميل)، يتم عرض القيمة الموجودة في حقل الحبة في حقل الإدخال.
html:submit
يُستخدم لإنشاء علامة HTML <input type="submit"...>
html:reset
يُستخدم لإنشاء علامة HTML <input type="reset"...>
html:button
يُستخدم لإنشاء علامة HTML <input type="button"...>

2.4.6. البيان المرتبط بالنموذج formulaire.personne.jsp

  • مع Struts، يجب أن يكون كل نموذج مرتبطًا بـ bean مسؤول عن تخزين قيم النموذج والحفاظ عليها في الجلسة الحالية. bean هو فئة Java يجب أن تلتزم بصيغة محددة. يجب أن يمتد bean المرتبط بنموذج ما إلى فئة ActionForm المحددة في مكتبة Struts:
public class FormulaireBean extends ActionForm {
  • يجب أن تتطابق أسماء سمات bean مع حقول النموذج (سمات خصائص علامات <html:text> الخاصة بالنموذج). استنادًا إلى الكود من النموذج السابق، يجب أن يحتوي bean على حقلين باسم name و age.
  • لكل حقل XX في النموذج، يجب أن يحدد bean طريقتين:
    • public void setXX(Type value): لتعيين قيمة لخاصية XX
    • public getXX(Value type): لاسترداد قيمة حقل XX

يمكن أن يكون الفول المرتبط بالنموذج السابق كما يلي:

package istia.st.struts.personne;

import org.apache.struts.action.ActionForm;

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;
  }
}

سنقوم بتجميع هذه الفئة باستخدام JBuilder.

2.4.7. اختبار عرض formulaire.personne.jsp

يتم وضع ملف formulaire.personne.jsp في مجلد views الخاص بتطبيق strutspersonne:

Image

  • يتم تعديل ملف 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>
    <action-mappings>
      <action
          path="/main"
          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>
</struts-config>

في ملف التكوين، نقوم بإنشاء عنوان URL جديد /form ليتولى معالجته وحدة التحكم Struts. سيتم إعادة توجيه عنوان URL /form.do إلى العرض /views/form.person.jsp. يتم وضع ملف struts-config.xml في مجلد WEB-INF.

  • نضع فئة FormulaireBean في WEB-INF/classes:

Image

  • نقوم بإعادة تشغيل Tomcat حتى يتم أخذ ملف struts-config.xml الجديد في الاعتبار، ثم نطلب عنوان URL http://localhost:8080/strutspersonne/formulaire.do:

Image

يتم عرض النموذج بشكل صحيح. قد نشعر بالفضول لمعرفة كيف تم "ترجمة" علامات <html:XX> المنتشرة في جميع أنحاء كود JSP الخاص بالنموذج:

<html>
    <meta http-equiv="pragma" content="no-cache"> 
    <head>
      <title>Personne - formulaire</title>
    <script language="javascript">
        function effacer(){
          with(document.frmPersonne){
            nom.value="";
          age.value="";
        }
      }
    </script>
  </head>

  <body>
      <center>

        <h2>Personne - formulaire</h2>
      <hr>
      <form name="frmPersonne" method="post" action="/strutspersonne/main.do">
          <table>
            <tr>
              <td>Nom</td>
            <td><input type="text" name="nom" size="20" value=""></td>
          </tr>

          <tr>
              <td>Age</td>
            <td><input type="text" name="age" size="3" value=""></td>
          </tr>
            <tr>
        </table>
        <table>
            <tr>

              <td><input type="submit" value="Envoyer"></td>
            <td><input type="reset" value="Rétablir"></td>
            <td><input type="button" name="btnEffacer" value="Effacer" onclick="effacer()"></td>
          </tr>
        </table>
      </form>
    </center>
  </body>
</html>

في النموذج الناتج، يعمل زر [Reset] وزر [Clear]. يقوم زر [Submit] بإعادة التوجيه إلى عنوان URL /strutspersonne/main.do. وفقًا لملف web.xml الخاص بالتطبيق، سيتولى وحدة التحكم Struts معالجة هذا الأمر. وفقًا لملف struts-config.html، يجب على وحدة التحكم إعادة توجيه الطلب إلى العرض /vues/main.html. دعونا نجرب ذلك:

Image

كل شيء يعمل كما هو متوقع. ما زلنا بحاجة إلى معالجة قيم النموذج فعليًا، أي كتابة فئة Action التي ستستقبل بيانات النموذج في كائن FormBean.