Skip to content

3. أساسيات تطوير الويب بلغة Java

ننتقل الآن إلى تطوير تطبيقات الويب الديناميكية، c.a.d. وهي تطبيقات يتم فيها إنشاء الصفحات HTML المرسلة إلى المستخدم بواسطة برامج.

3.1. إنشاء مشروع ويب في Eclipse

سنقوم بتطوير أول تطبيق ويب باستخدام Eclipse/Tomcat. سنتبع نهجًا مشابهًا للنهج المستخدم لإنشاء تطبيق ويب بدون Eclipse. بعد تشغيل Eclipse، نقوم بإنشاء مشروع جديد:

Image

الذي نحدده كمشروع ويب ديناميكي:

Image

في الصفحة الأولى من مساعد الإنشاء، نحدد اسم المشروع [1] وموقعه [2]:

Image

في الصفحة الثانية من المساعد، نقبل القيم الافتراضية:

Image

تطلب منا الصفحة الأخيرة من المساعد تحديد سياق التطبيق [3]:

Image

بمجرد تأكيد المعالج بواسطة [Finish]، يتصل Eclipse بالموقع [http://java.sun.com] لاسترداد بعض المستندات التي يرغب في تخزينها مؤقتًا لتجنب الوصول غير الضروري إلى الشبكة. ثم يُطلب الحصول على موافقة الترخيص:

Image

نوافق على ذلك. يقوم Eclipse بإنشاء مشروع الويب. لعرضه، يستخدم بيئة، تسمى المنظور، تختلف عن تلك المستخدمة في مشروع Java التقليدي:

Image

المنظور المرتبط بمشروع الويب هو المنظور J2EE. نقبله لنرى... والنتيجة التي نحصل عليها هي التالية:

Image

المنظور J2EE معقد بشكل غير ضروري بالنسبة لمشاريع الويب البسيطة. في هذه الحالة، يكفي استخدام منظور Java. للحصول عليه، نستخدم الخيار [Window -> Open perspective -> Java]:

Image

src: سيحتوي على كود Java لفئات التطبيق بالإضافة إلى الملفات التي يجب أن تكون موجودة في Classpath للتطبيق.

build/classes (غير موضح): سيحتوي على ملفات .class للفئات المُجمَّعة بالإضافة إلى نسخة من جميع الملفات بخلاف ملفات .java الموجودة في src. غالبًا ما تستخدم تطبيقات الويب ما يُعرف بملفات "الموارد" التي يجب أن تكون موجودة في مجلد Classpath الخاص بالتطبيق، c.a.d. مجموعة المجلدات التي يتم استكشافها بواسطة JVM عندما يشير التطبيق إلى فئة، سواء أثناء التحويل البرمجي أو أثناء التنفيذ. يضمن Eclipse أن يكون المجلد build/classes جزءًا من الويب. يتم وضع ملفات "الموارد" في المجلد src مع العلم أن Eclipse سيعيد نسخها تلقائيًا إلى build/classes.

WebContent: سيحتوي على موارد تطبيق الويب التي لا يجب أن تكون موجودة في في Classpath الخاص بالتطبيق.

WEB-INF/lib: سيحتوي على أرشيفات .jar التي يحتاجها تطبيق الويب.

دعونا نلقي نظرة على محتوى الملف [WEB-INF/web.xml] الذي يقوم بتكوين التطبيق [personne]:


<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>    personne</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
        <welcome-file>index.htm</welcome-file>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.html</welcome-file>
        <welcome-file>default.htm</welcome-file>
        <welcome-file>default.jsp</welcome-file>
    </welcome-file-list>
</web-app>

لقد سبق أن تعرفنا على هذا النوع من التكوين عندما درسنا إنشاء صفحات البداية في الفقرة 2.3.4. لا يقوم هذا الملف بأي شيء سوى تعريف سلسلة من صفحات البداية. نحتفظ بالصفحة الأولى فقط. يصبح ملف [web.xml] كما يلي:


<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>personne</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>

يجب أن يتوافق محتوى الملف XML أعلاه مع قواعد الصياغة المحددة في الملف المشار إليه بالسمة [xsi:schemaLocation] في علامة الافتتاح <web-app>. هذا الملف هو هنا [http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd]. وهو ملف XML يمكن طلبه مباشرةً باستخدام متصفح. إذا كان المتصفح حديثًا بما يكفي، فسيتمكن من عرض ملف XML:

Image

سيحاول Eclipse التحقق من صحة المستند XML باستخدام ملف .xsd المحدد في السمة [xsi:schemaLocation] لعلامة البداية <web-app>. ولهذا الغرض، سيقوم بإجراء اتصال بالشبكة. إذا كان جهاز الكمبيوتر الخاص بك متصلاً بشبكة خاصة، فيجب عليك إخبار Eclipse بالجهاز الذي يجب استخدامه للخروج من الشبكة الخاصة، والذي يُسمى الوكيل HTTP. يتم ذلك باستخدام الخيار [Window -> Preferences -> Internet]:

Image

نضع علامة (1) إذا كنا على شبكة خاصة. في (2)، نحدد اسم الجهاز الذي يدعم الوكيل HTTP وفي (3) منفذ الاستماع الخاص به. وأخيرًا، في (4)، نحدد الأجهزة التي لا يجب أن تمر عبر الوكيل، وهي الأجهزة الموجودة على نفس الشبكة الخاصة التي يعمل عليها الجهاز الذي نستخدمه.

سنقوم الآن بإنشاء ملف [index.html] للصفحة الرئيسية.

3.2. إنشاء صفحة رئيسية

نضغط بزر الفأرة الأيمن على المجلد [WebContent] ثم نختار الخيار [New -> Other]:

Image

نختار النوع [HTML] ونقوم بـ [Next] ->

Image

أعلاه، نختار المجلد الأصلي [WebContent] في (1) أو (2) ثم نحدد في (3) اسم الملف المراد إنشاؤه. بعد ذلك، ننتقل إلى الصفحة التالية من المعالج:

Image

باستخدام (1)، يمكننا إنشاء ملف HTML مملوء مسبقًا بـ (2). إذا قمنا بإلغاء تحديد (1)، فسننشئ ملف HTML فارغًا. نحتفظ بعلامة الاختيار (1) للاستفادة من هيكل الكود. ننهي المعالج بـ [Finish]. يتم عندئذٍ إنشاء الملف [index.html]:

Image

بالمحتوى التالي:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>

</body>
</html>

نقوم بتعديل هذا الملف على النحو التالي:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Application personne</title>
</head>
<body>
Application personne active...
<br>
<br>
Vous êtes sur la page d'accueil
</body>
</html>

3.3. اختبار الصفحة الرئيسية

إذا لم تكن موجودة، فلنعرض العرض [Servers] باستخدام الخيار [Window - > Show View -> Other -> Servers] ثم نضغط بزر الفأرة الأيمن على خادم Tomcat 5.5:

Image

تسمح الخيار [Add and Remove Objects] أعلاه بإضافة / إزالة تطبيقات الويب من خادم Tomcat:

Image

تظهر مشاريع الويب المعروفة في Eclipse في (1). يمكن تسجيلها على خادم Tomcat من خلال (2). تظهر تطبيقات الويب المسجلة لدى خادم Tomcat في (4). يمكن إلغاء تسجيلها باستخدام (3). لنقم بتسجيل المشروع [personne]:

Image

ثم ننهي مساعد التسجيل بـ [Finish]. تظهر طريقة العرض [Servers] أن المشروع [personne] قد تم تسجيله على Tomcat:

Image

الآن، لنقم بتشغيل خادم Tomcat:

لنشغل متصفح الويب:

Image

ثم نطلب عنوان URL [http://localhost:8080/personne]. هذا العنوان هو عنوان جذر تطبيق الويب. لم يتم طلب أي مستند. في هذه الحالة، يتم عرض الصفحة الرئيسية للتطبيق. إذا لم تكن موجودة، يتم الإبلاغ عن خطأ. هنا، الصفحة الرئيسية موجودة. إنه الملف [index.html] الذي أنشأناه سابقًا. والنتيجة التي تم الحصول عليها هي التالية:

Image

وهي تتوافق مع ما كان متوقعًا. الآن، لنستخدم متصفحًا خارجيًّا عن Eclipse ونطلب نفس عنوان URL:

Image

وبالتالي، فإن تطبيق الويب [personne] معروف أيضًا خارج Eclipse.

3.4. إنشاء نموذج HTML

نقوم الآن بإنشاء مستند ثابت HTML [formulaire.html] في المجلد [personne]:

Image

لإنشائه، سنتبع الإجراء الموضح في الفقرة 3.2، صفحة 33. وسيكون محتواه كما يلي:


<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>Personne - formulaire</title>
</head>
<body>
  <center>
    <h2>Personne - formulaire</h2>
    <hr>
    <form action="" method="post">
    <table>
      <tr>
        <td>Nom</td>
        <td><input name="txtNom" value="" type="text" size="20"></td>
      </tr>
      <tr>
        <td>Age</td>
        <td><input name="txtAge" value="" type="text" size="3"></td>
      </tr>
    </table>
    <table>
      <tr>
        <td><input type="submit" value="Envoyer"></td>
        <td><input type="reset" value="Retablir"></td>
        <td><input type="button" value="Effacer"></td>
      </tr>
    </table>
    </form>
  </center>
</body>
</html>

الرمز HTML أعلاه يتوافق مع النموذج أدناه:

Image

النوع HTML
الاسم
الرمز HTML
الدور
1
<input type= "text ">
txtNom
السطر 14
إدخال الاسم
2
<input type= "text ">
txtAge
السطر 18
إدخال العمر
3
<input type= "submit ">
 
السطر 23
إرسال القيم المدخلة إلى الخادم على الرابط /personne1/main
4
<input type= "reset ">
 
السطر 24
لإعادة الصفحة إلى الحالة التي استقبلها المتصفح بها في البداية
5
<input type= "button ">
 
السطر 25
لمسح محتويات حقول الإدخال [1] و [2]

لنحفظ المستند في المجلد <personne>/WebContent. لنقم بتشغيل Tomcat إذا لزم الأمر. باستخدام متصفح، لنطلب URL http://localhost:8080/personne/formulaire.html :

Image

البنية العميل/الخادم لهذا التطبيق الأساسي هي كما يلي:

Image

يقع خادم الويب بين المستخدم وتطبيق الويب ولم يتم تمثيله هنا. [formulaire.html] هو مستند ثابت يقدم نفس المحتوى لكل طلب من العميل. تهدف برمجة الويب إلى إنشاء محتوى ملائم لطلب العميل. يتم إنشاء هذا المحتوى بواسطة برنامج. الحل الأول هو استخدام صفحة JSP (صفحة خادم Java) بدلاً من الملف الثابت HTML. وهذا ما سنراه الآن.

3.5. إنشاء صفحة JSP


قراءات [ref1]: الفصل 1، الفصل 2: 2.2، 2.2.1، 2.2.2، 2.2.3، 2.2.4


يتم تحويل بنية العميل/الخادم السابقة على النحو التالي:

Image

صفحة JSP هي شكل من أشكال صفحة HTML التي تم تعيين معلماتها. لا تتلقى بعض عناصر الصفحة قيمتها إلا في وقت التنفيذ. يتم حساب هذه القيم بواسطة البرنامج. وبالتالي، لدينا صفحة ديناميكية: قد تؤدي الطلبات المتتالية على الصفحة إلى استجابات مختلفة. نسمي هنا بالاستجابة الصفحة HTML التي يعرضها متصفح العميل. في النهاية، لا يزال المتصفح يتلقى مستند HTML. يتم إنشاء هذا المستند HTML بواسطة خادم الويب انطلاقًا من الصفحة JSP. وتُستخدم هذه الأخيرة كنموذج. ويتم استبدال عناصرها الديناميكية بقيمها الفعلية عند إنشاء المستند HTML.

لإنشاء صفحة JSP، نضغط بزر الفأرة الأيمن على المجلد [WebContent] ثم نختار الخيار [New -> Other]:

Image

نختار النوع [JSP] ونقوم بـ [Next] ->

Image

أعلاه، نختار المجلد الأصلي [WebContent] في (1) أو (2) ثم نحدد في (3) اسم الملف المراد إنشاؤه. بعد ذلك، ننتقل إلى الصفحة التالية من المعالج:

Image

باستخدام (1)، يمكننا إنشاء ملف JSP مملوء مسبقًا بـ (2). إذا قمنا بإلغاء تحديد (1)، فسننشئ ملف JSP فارغًا. نحتفظ بعلامة الاختيار (1) للاستفادة من هيكل الكود. ننهي المعالج بـ [Finish]. يتم عندئذٍ إنشاء الملف [formulaire.jsp]:

Image

بالمحتوى التالي:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>

</body>
</html>

تشير السطر 1 إلى أننا نتعامل مع صفحة JSP. نقوم بتحويل النص أعلاه على النحو التالي:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
    // يتم استرداد المعلمات
  String nom=request.getParameter("txtNom");
  if(nom==null) nom="inconnu";
  String age=request.getParameter("txtAge");
  if(age==null) age="xxx";  
%>

<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
      <title>Personne - formulaire</title>
  </head>
  <body>
      <center>
        <h2>Personne - formulaire</h2>
      <hr>
      <form action="" method="post">
          <table>
            <tr>
              <td>Nom</td>
            <td><input name="txtNom" value="<%= nom %>" type="text" size="20"></td>
          </tr>
          <tr>
              <td>Age</td>
            <td><input name="txtAge" value="<%= age %>" type="text" size="3"></td>
          </tr>
        </table>
        <table>
            <tr>
              <td><input type="submit" value="Envoyer"></td>
            <td><input type="reset" value="Rétablir"></td>
            <td><input type="button" value="Effacer"></td>
          </tr>
        </table>
      </form>
    </center>
  </body>
</html>

أصبح المستند الذي كان ثابتًا في البداية ديناميكيًا الآن من خلال إدخال كود Java. بالنسبة لهذا النوع من المستندات، سنقوم دائمًا بما يلي:

  • نضع كود Java منذ بداية المستند لاسترداد المعلمات اللازمة لعرض المستند. غالبًا ما تكون هذه المعلمات موجودة في كائن request. يمثل هذا الكائن طلب العميل. وقد يمر هذا الطلب عبر العديد من السيرفلتات والصفحات JSP التي قد تكون أثرت محتواه. هنا، سيصل إلينا مباشرةً من المتصفح.
  • يوجد كود HTML أدناه. سيكتفي في الغالب بعرض المتغيرات التي تم حسابها مسبقًا في كود Java باستخدام علامات <%= variable %>. تجدر الإشارة هنا إلى أن علامة = ملتصقة بعلامة %. وهذا سبب شائع لحدوث الأخطاء.

ما الذي يفعله المستند الديناميكي السابق؟

  • الأسطر 6-9: يسترد من الاستعلام معلمتين تسميان [txtNom] و [txtAge] ويضع قيمهما في المتغيرين [nom] (السطر 6) و [age] (السطر 8). إذا لم يعثر على المعلمات، فإنه يعطي المتغيرات المرتبطة بها قيمًا افتراضية.
  • ويعرض قيمة المتغيرين [nom, age] في الكود HTML التالي (السطران 25 و29).

لنقم بإجراء اختبار أولي. لنقم بتشغيل Tomcat إذا لزم الأمر، ثم باستخدام متصفح، نطلب URL http://localhost:8080/personne/formulaire.jsp :

Image

تم استدعاء المستند formulaire.jsp دون تمرير أي معلمات. وبالتالي، تم عرض القيم الافتراضية. الآن لنطلب URL http://localhost:8080/personne/formulaire.jsp?txtNom=martin&txtAge=14 :

Image

هذه المرة، قمنا بتمرير المعلمات txtNom و txtAge التي ينتظرها إلى المستند formulaire.jsp. وبالتالي، قام بعرضها. نعلم أن هناك طريقتين لتمرير المعلمات إلى مستند ويب: GET و POST. في كلتا الحالتين، توجد المعلمات التي تم تمريرها في الكائن المحدد مسبقًا request. هنا، تم تمريرها بواسطة الطريقة GET.

3.6. إنشاء سيرفلت


قراءات [ref1]: الفصل 1، الفصل 2: 2.1، 2.1.1، 2.1.2، 2.3.1


في الإصدار السابق، تمت معالجة طلب العميل بواسطة صفحة JSP. عند أول استدعاء لهذه الصفحة، يقوم خادم الويب، وهو Tomcat هنا، بإنشاء فئة Java من هذه الصفحة وتجميعها. ونتيجة هذا التجميع هي التي تعالج في النهاية طلب العميل. الفئة التي تم إنشاؤها من الصفحة JSP هي سيرفلت لأنها تنفذ واجهة [javax.Servlet]:

Image

يمكن معالجة طلب العميل بواسطة أي فئة تنفذ هذه الواجهة. نقوم الآن بإنشاء فئة من هذا النوع: ServletFormulaire. يتم تحويل بنية العميل/الخادم السابقة على النحو التالي:

Image

مع بنية الصفحة JSP، تم إنشاء المستند HTML المرسل إلى العميل بواسطة خادم الويب من الصفحة JSP التي كانت بمثابة نموذج. هنا، سيتم إنشاء المستند HTML المرسل إلى العميل بالكامل بواسطة السيرفلت.

3.6.1. إنشاء السيرفلت

في Eclipse، انقر بزر الماوس الأيمن على المجلد [src] واختر خيار إنشاء فئة:

Image

ثم نحدد خصائص الفئة المراد إنشاؤها:

Image

في (1)، نضع اسم الحزمة، وفي (2) اسم الفئة المراد إنشاؤها. يجب أن تكون هذه الفئة مشتقة من الفئة المحددة في (3). لا داعي لكتابة الاسم الكامل لهذه الفئة بنفسك. يتيح الزر (4) الوصول إلى الفئات الموجودة حاليًا في Classpath لتطبيق الويب:

Image

في (1) نكتب اسم الفئة المطلوبة. نحصل في (2) على فئات Classpath التي يحتوي اسمها على السلسلة المكتوبة في (1).

بعد التحقق من صحة مساعد الإنشاء، يتم تعديل مشروع الويب [personne] على النحو التالي:

Image

تم إنشاء الفئة [ServletFormulaire] مع هيكل أساسي للكود:

Image

تُظهر لقطة الشاشة أعلاه أن Eclipse يشير إلى [warning] في السطر الذي يعلن الفئة. لنضغط على الرمز (المصباح) الذي يشير إلى [warning]:

Image

بعد النقر على (1)، يتم عرض حلول لإزالة [warning] في (2). يؤدي اختيار أحدها إلى ظهور التعديل الذي سيترتب على هذا الاختيار في (3).

أحدثت Java 1.5 تغييرات في لغة Java، وما كان صحيحًا في إصدار سابق قد يصبح الآن عرضة لـ [warnings]. لا تشير هذه إلى أخطاء قد تمنع ترجمة الفئة. إنها موجودة لتلفت انتباه المطور إلى نقاط في الكود يمكن تحسينها. يشير [warning] الحالي إلى أن الفئة يجب أن تحتوي على رقم إصدار. ويُستخدم هذا الرقم لتسلسل/إلغاء تسلسل الكائنات، c.a.d. عندما يجب تحويل كائن Java .class الموجود في الذاكرة إلى سلسلة من البتات المرسلة بالتسلسل في تدفق كتابة أو العكس عندما يجب إنشاء كائن Java .class الموجود في الذاكرة من سلسلة من البتات المقروءة بالتسلسل في تدفق قراءة. كل هذا بعيد جدًا عن اهتماماتنا الحالية. لذا سنطلب من المُجمع تجاهل هذا التحذير باختيار الحل [Add @SuppressWarnings ...]. يصبح الكود عندئذٍ كما يلي:

Image

لم يعد هناك [warning]. يُسمى السطر المضاف "تعليقًا"، وهو مفهوم ظهر مع Java 1.5. سنكمل هذا الكود لاحقًا.

3.6.2. مسار فئة مشروع Eclipse

يُعد Classpath لتطبيق Java هو مجموعة المجلدات و archives.jar التي يتم استكشافها عندما يقوم المُجمِّع بتجميعه أو عندما تقوم JVM بتنفيذه. هذان المساران ليسا متطابقين بالضرورة، حيث أن بعض الفئات لا تكون مفيدة إلا عند التنفيذ وليس عند التحويل البرمجي. يحتوي كل من مترجم Java و JVM على وسيطة تسمح بتحديد Classpath للتطبيق المراد ترجمته أو تنفيذه. وبطريقة شفافة إلى حد ما بالنسبة للمستخدم، يضمن Eclipse إنشاء هذه الوسيطة وتمريرها إلى JVM.

كيف يمكن معرفة عناصر Classpath لمشروع Eclipse؟ باستخدام الخيار [<projet> / Build Path / Configure Build Path]:

Image

نحصل عندئذٍ على مساعد التكوين التالي:

Image

تتيح علامة التبويب (1) [Libraries] تحديد قائمة ملفات .jar التي تشكل جزءًا من ملف Classpath الخاص بالتطبيق. وبالتالي، يتم استكشافها بواسطة ملف JVM عندما يطلب التطبيق فئة ما. تسمح الأزرار [2] و [3] بإضافة أرشيفات إلى Classpath. يتيح الزر [2] تحديد الأرشيفات الموجودة في مجلدات المشاريع التي يديرها Eclipse، بينما يتيح الزر [3] تحديد أي أرشيف في نظام ملفات الكمبيوتر.

يظهر أعلاه ثلاث مكتبات (Libraries):

  • [JRE System Library]: مكتبة أساسية لمشاريع Java في Eclipse:

Image

  • [Tomcat v5.5 runtime]: مكتبة مقدمة من خادم Tomcat. وهي تتضمن الفئات اللازمة لتطوير الويب. يتم تضمين هذه المكتبة في أي مشروع ويب في Eclipse تم ربطه بخادم Tomcat.

Image

الأرشيف [servlet-api.jar] هو الذي يحتوي على الفئة [javax.servlet.http.HttpServlet]، وهي الفئة الأم للفئة [ServletFormulaire] التي نقوم بإنشائها حالياً. ونظرًا لوجود هذا الأرشيف في Classpath للتطبيق، فقد تم اقتراحه كفئة أصلية في المساعد المذكور أدناه.

Image

ولو لم يكن الأمر كذلك، لما ظهرت ضمن اقتراحات [2]. لذا، إذا أردنا في هذا المساعد الإشارة إلى فئة أصلية ولم يتم اقتراحها، فهذا يعني إما أننا أخطأنا في اسم هذه الفئة، أو أن الأرشيف الذي يحتوي عليها غير موجود في Classpath الخاص بالتطبيق.

  • يجمع [Web App Libraries] الأرشيفات الموجودة في مجلد [WEB-INF/lib] الخاص بالمشروع. وهو فارغ هنا:

Image

توجد أرشيفات Classpath الخاصة بمشروع Eclipse في مستكشف المشاريع. على سبيل المثال، بالنسبة لمشروع الويب [personne]:

Image

يتيح لنا مستكشف المشاريع الوصول إلى محتوى هذه الأرشيفات:

Image

وكما هو موضح أعلاه، يمكننا أن نرى أن الأرشيف [servlet-api.jar] هو الذي يحتوي على الفئة [javax.servlet.http.HttpServlet].

3.6.3. تكوين السيرفلت


قراءات [ref1]: الفصل 2: 2.3، 2.3.1، 2.3.2، 2.3.3، 2.3.4


يُستخدم الملف [WEB-INF/web.xml] لتكوين تطبيق الويب:

Image

هذا الملف، الخاص بمشروع [personne]، هو حاليًا كما يلي (انظر الصفحة 32):


<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>personne</display-name>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>

وهو يشير فقط إلى وجود ملف الصفحة الرئيسية (السطر 8). نقوم بتطويره للإعلان عن:

  • وجود السيرفلت [ServletFormulaire]
  • ملفات URL التي تعالجها هذه الخدمة
  • معلمات تهيئة السيرفلت

سيكون ملف web.xml لتطبيقنا الشخصي كما يلي:


<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>personne</display-name>
    <servlet>
        <servlet-name>formulairepersonne</servlet-name>
        <servlet-class>
            istia.st.servlets.personne.ServletFormulaire
        </servlet-class>
        <init-param>
            <param-name>defaultNom</param-name>
            <param-value>inconnu</param-value>
        </init-param>
        <init-param>
            <param-name>defaultAge</param-name>
            <param-value>XXX</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>formulairepersonne</servlet-name>
        <url-pattern>/formulaire</url-pattern>
    </servlet-mapping>
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>

النقاط الرئيسية في ملف التكوين هذا هي كما يلي:

  • السطور 7-24 مرتبطة بوجود الخدمة [ServletFormulaire]
  • الأسطر 7-20: يتم تكوين السيرفلت بين العلامتين <servlet> و </servlet>. يمكن أن يحتوي التطبيق على عدة سيرفلتات وبالتالي على عدة أقسام تكوين <servlet>...</servlet>.
  • السطر 8: تحدد علامة <servlet-name> اسمًا للخادم الصغير - يمكن أن يكون أي اسم
  • الأسطر 9-11: تحدد العلامة <servlet-class> الاسم الكامل للفئة المطابقة للخادم الصغير. سيبحث Tomcat عن هذه الفئة في ملف Classpath التابع لمشروع الويب [personne]. وسيجدها في ملف [build/classes]:

Image

  • السطور 12-15: تُستخدم العلامة <init-param> لتمرير معلمات التكوين إلى السيرفلت. عادةً ما تُقرأ هذه المعلمات في طريقة init الخاصة بالسيرفلت لأن معلمات التكوين الخاصة بها يجب أن تكون معروفة منذ تحميلها لأول مرة.
  • الأسطر 13-14: تحدد العلامة <param-name> اسم المعلمة و<param-value> قيمتها.
  • تحدد الأسطر 12-15 معلمة [defaultNom,"inconnu"]، وتحدد الأسطر 16-19 معلمة [defaultAge,"XXX"]
  • السطور 21-24: تُستخدم العلامة <servlet-mapping> لربط سيرفلت (servlet-name) بنموذج URL (url-pattern). هنا النموذج بسيط. فهو ينص على أنه في كل مرة يكون فيها URL على شكل /formulaire، يجب استخدام السيرفلت formulairepersonne، c.a.d. الفئة [istia.st.servlets.ServletFormulaire] (الأسطر 8-11). وبالتالي، لا يوجد سوى عنوان URL واحد مقبول من قبل السيرفلت [formulairepersonne].

3.6.4. رمز الخادم [ServletFormulaire]

سيكون لبرنامج الخدمة [ServletFormulaire] الكود التالي:

package istia.st.servlets.personne;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class ServletFormulaire extends HttpServlet {

    // معلمات المثيل
    private String defaultNom = null;
    private String defaultAge = null;

    // التشغيل
    public void init() {
        // يتم استرداد معلمات تهيئة السيرفلت
        ServletConfig config = getServletConfig();
        defaultNom = config.getInitParameter("defaultNom");
        if (defaultNom == null)
            defaultNom = "NNNNNNNNNNNNNNN";
        defaultAge = config.getInitParameter("defaultAge");
        if (defaultAge == null)
            defaultAge = "AAA";
    }

    // GET
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

        // استرداد معلمات النموذج
        String nom = request.getParameter("txtNom");
        if (nom == null) {
            nom = defaultNom;
        }
        String age = request.getParameter("txtAge");
        if (age == null) {
            age = defaultAge;
        }
        // عرض النموذج
        response.setContentType("text/html");
        PrintWriter out = response.getWriter();
        out.println(
                "<html>"+
                  "<head>"+
                    "<title>Personne - formulaire</title>"+
                  "</head>"+
                  "<body>"+
                    "<center>"+
                      "<h2>Personne - formulaire</h2>"+
                      "<hr>"+
                      "<form action='' method='post'>"+
                        "<table>"+
                          "<tr>"+
                            "<td>Nom</td>"+
                            "<td><input name='txtNom' value='"+nom+"' type='text' size='20'></td>"+
                          "</tr>"+
                          "<tr>"+
                            "<td>Age</td>"+
                            "<td><input name='txtAge' value='"+ age +"' type='text' size='3'></td>"+
                          "</tr>"+
                        "</table>"+
                        "<table>"+
                          "<tr>"+
                            "<td><input type='submit' value='Envoyer'></td>"+
                            "<td><input type='reset' value='Rétablir'></td>"+
                            "<td><input type='button' value='Effacer'></td>"+
                          "</tr>"+
                        "</table>"+
                      "</form>"+
                    "</center>"+
                  "</body>"+
                "</html>"
      );
    }

    // POST
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        // نمرر الأمر إلى GET
        doGet(request, response);
    }
}

بمجرد قراءة السيرفلت، يمكن ملاحظة أنها أكثر تعقيدًا بكثير من الصفحة المقابلة لها JSP. وهذه قاعدة عامة: السيرفلت غير ملائمة لتوليد كود HTML. صفحات JSP هي المصممة لهذا الغرض. سنعود إلى هذا الموضوع لاحقًا. لنوضح بعض النقاط المهمة في السيرفلت أعلاه:

  • عندما يتم استدعاء السيرفلت للمرة الأولى، يتم استدعاء طريقة init (السطر 20). هذه هي الحالة الوحيدة التي يتم فيها استدعاء هذه الطريقة.
  • إذا تم استدعاء السيرفلت بواسطة الطريقة HTTP GET، يتم استدعاء الطريقة doGet (السطر 32) لمعالجة طلب العميل.
  • إذا تم استدعاء السيرفلت بواسطة الطريقة HTTP POST، يتم استدعاء الطريقة doPost (السطر 82) لمعالجة طلب العميل.

تُستخدم الطريقة init هنا لاسترداد قيم معلمات التهيئة المسماة "defaultNom" و"defaultAge" في [web.xml]. تعد الطريقة init التي يتم تنفيذها عند التحميل الأولي للـ servlet المكان المناسب لاسترداد محتوى الملف [web.xml].

  • السطر 22: يتم استرداد تكوين [config] لمشروع الويب. يعكس هذا الكائن محتوى ملف [WEB-INF/web.xml] الخاص بالتطبيق.
  • السطر 23: يتم استرداد القيمة من النوع String للمعلمة المسماة "defaultNom" من هذه التهيئة. ستكون قيمة هذه المعلمة هي اسم شخص ما. وإذا لم يكن موجودًا، فسنحصل على القيمة null.
  • السطران 24-25: إذا لم يكن المعامل المسمى "defaultNom" موجودًا، فإننا نعطي قيمة افتراضية للمتغير [defaultNom].
  • السطور 26-29: نفعل الشيء نفسه للمعلمة المسماة "defaultAge".

تشير الطريقة doPost إلى الطريقة doGet. وهذا يعني أنه يمكن للعميل إرسال معلماته إما عبر POST أو GET.

الطريقة doGet:

  • السطر 32: تتلقى الطريقة معلمتين هما request و response. request هو كائن يمثل كامل طلب العميل. وهو من النوع HttpServletRequest الذي يعد واجهة. response هو من النوع HttpServletResponse الذي يعد أيضًا واجهة. يستخدم كائن response لإرسال استجابة إلى العميل.
  • يُستخدم request.getParameter("param") لاسترداد قيمة المعلمة التي تحمل الاسم param من طلب العميل. في السطر 36، يتم استرداد قيمة المعلمة "txtNom"، وفي السطر 40 يتم استرداد قيمة المعلمة "txtAge". إذا لم تكن هذه المعلمات موجودة في الطلب، يتم الحصول على القيمة null كقيمة للمعلمة.
  • السطور 37-39: إذا لم يكن المعامل " txtNom " موجودًا في الاستعلام، يتم تعيين الاسم الافتراضي " defaultNom " الذي تم تهيئته في الطريقة init للمتغير " nom ". ويتم إجراء الشيء نفسه في الأسطر 41-43 بالنسبة للعمر.
  • السطر 45: تُستخدم response.setContentType(String) لتعيين قيمة رأس HTTP Content-type. يُشير هذا الرأس للعميل إلى طبيعة المستند الذي سيتلقاه. يُشير النوع text/html إلى مستند HTML.
  • السطر 46: تُستخدم response.getWriter() للحصول على تدفق كتابة إلى العميل
  • الأسطر 47-78: يتم كتابة المستند HTML المراد إرساله إلى العميل في تدفق الكتابة الذي تم الحصول عليه في السطر 46.

سيؤدي تجميع هذا السيرفلت إلى إنتاج ملف .class في المجلد [build/classes] التابع للمشروع [personne]:

Image

يُرجى من القارئ الرجوع إلى دليل Java الخاص بالبرمجيات الخادمة. ويمكن الاستعانة ببرنامج Tomcat في ذلك. في صفحة الدخول إلى Tomcat 5، يوجد رابط [Documentation]:

Image

يؤدي هذا الرابط إلى صفحة يُدعى القارئ إلى استكشافها. الرابط الخاص بوثائق السيرفلت هو التالي:

Image

3.6.5. اختبار السيرفلت

نحن جاهزون لإجراء الاختبار. لنقم بتشغيل خادم Tomcat إذا لزم الأمر.

Image

ثم نطلب باستخدام متصفح URL [http://localhost:8080/personne/formulaire]. نطلب هنا عنوان URL [/formulaire] من السياق [/personne]. يشير الملف [web.xml] في هذا السياق إلى أن عنوان URL [/formulaire] تتم معالجته بواسطة السيرفلت الذي يحمل الاسم [formulairepersonne]. في نفس الملف، يشار إلى أن هذه الخدمة هي الفئة [istia.st.servlets.ServletFormulaire]. وبالتالي، سيكلف Tomcat هذه الفئة بمعالجة طلب العميل. إذا لم تكن الفئة محملة بالفعل، فسيتم تحميلها. وستبقى بعد ذلك في الذاكرة للاستخدام في الطلبات المستقبلية.

نحصل على النتيجة التالية باستخدام متصفح Eclipse الداخلي:

Image

نحصل على القيم الافتراضية للاسم والعمر، وهي القيم المسجلة في الملف [web.xml]. لنطلب الآن URL [http://localhost:8080/personne/formulaire?txtNom=tintin&txtAge=30] :

Image

هذه المرة، نحصل على المعلمات التي تم تمريرها في الاستعلام. يُطلب من القارئ إعادة قراءة كود السيرفلت [ServletFormulaire] إذا لم يفهم هذين النتيجتين.

3.6.6. إعادة التحميل التلقائي لسياق تطبيق الويب

دعونا نطلق Tomcat:

Image

ثم نقوم بتعديل كود السيرفلت على النحو التالي:

    // GET
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

        // يتم استرداد معلمات النموذج
        String nom = request.getParameter("txtNom");
        if (nom == null) {
            nom = "--"+defaultNom+"--";
        }
        String age = request.getParameter("txtAge");
        if (age == null) {
            age = defaultAge;
        }
...
  • تم تعديل السطر 8

لنحفظ الفئة الجديدة. سيؤدي هذا الحفظ، من جانب Eclipse، إلى إعادة تجميع تلقائي للفئة [ServletFormulaire] التي سيكتشفها Tomcat. ثم سيعيد تحميل سياق تطبيق الويب [personne] لمراعاة التعديلات. يظهر هذا في سجلات العرض [console]:

Image

لنطلب عنوان URL [http://localhost:8080/personne/formulaire] دون إعادة تشغيل Tomcat:

Image

تم أخذ التعديل الذي تم إجراؤه في الاعتبار.

الآن، لنقوم بتعديل الملف [web.xml] بالطريقة التالية:


<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>personne</display-name>
    <servlet>
        <servlet-name>formulairepersonne</servlet-name>
...
        <init-param>
            <param-name>defaultNom</param-name>
            <param-value>INCONNU</param-value>
        </init-param>
...
    </servlet>
...
</web-app>
  • تم تعديل السطر 12

بعد ذلك، لنحفظ الملف الجديد [web.xml]. في عرض [console]، لا يوجد أي سجل يشير إلى إعادة تحميل سياق التطبيق. لنطلب عنوان URL [http://localhost:8080/personne/formulaire] دون إعادة تشغيل Tomcat:

Image

لم يتم أخذ التعديل الذي تم إجراؤه في الاعتبار. لنعيد تشغيل Tomcat [clic droit sur serveur -> Restart -> Start]:

Image

ثم نطلب الرابط [http://localhost:8080/personne/formulaire] مرة أخرى:

Image

هذه المرة، يمكن رؤية التعديل الذي تم إجراؤه في [web.xml].

وبالتالي، فإن التعديل الذي تم إجراؤه في [web.xml] لا يؤدي إلى إعادة تحميل تلقائي للتطبيق بحيث يأخذ في الاعتبار ملف التكوين الجديد. لإجبار التطبيق على إعادة التحميل، يمكن إعادة تشغيل Tomcat كما فعلنا من قبل، ولكن هذه العملية بطيئة إلى حد ما. من الأفضل استخدام أداة [manager] لإدارة التطبيقات المنشورة في Tomcat. ولتحقيق ذلك، يجب أن يكون Tomcat قد تم تكوينه داخل Eclipse كما هو موضح في الفقرة 2.5.

أولاً، باستخدام متصفح Eclipse الداخلي، اطلب عنوان URL [http://localhost:8080] ثم اتبع الرابط [Tomcat Manager]، كما هو موضح في نهاية الفقرة 2.5:

Image

لنفتح متصفحًا ثانيًا [clic droit sur le navigateur -> New Editor]:

في هذا المتصفح الثاني، لنطلب عنوان URL [http://localhost:8080/formulaire]:

Image

لنقوم بتعديل الملف [web.xml] بالطريقة التالية ثم نحفظه:


<!--  ServletFormulaire -->
    <servlet>
        <servlet-name>formulairepersonne</servlet-name>
        <servlet-class>
            istia.st.servlets.personne.ServletFormulaire
        </servlet-class>
        <init-param>
            <param-name>defaultNom</param-name>
            <param-value>YYY</param-value>
        </init-param>
        <init-param>
            <param-name>defaultAge</param-name>
            <param-value>XXX</param-value>
        </init-param>
    </servlet>

ثم نطلب مرة أخرى عنوان URL [http://localhost:8080/formulaire]. يمكننا ملاحظة أن التعديل لم يتم أخذه في الاعتبار. الآن، ننتقل إلى المتصفح الأول ونعيد تحميل التطبيق [personne]:

Image

ثم نطلب مرة أخرى عنوان URL [http://localhost:8080/formulaire] باستخدام المتصفح الثاني:

Image

تم أخذ تعديل [web.xml] في الاعتبار. في الممارسة العملية، من المفيد فتح متصفح على تطبيق [manager] من Tomcat لإدارة هذا النوع من الحالات.

3.7. التعاون بين السيرفلت والصفحات JSP


قراءات [ref1]: الفصل 2: 2.3.7


لنعد إلى البنيتين اللتين درسناهما:

Image

لا تعتبر أي من هاتين البنيتين مرضية. فكلتاهما تعاني من عيب خلط تقنيتين: تقنية البرمجة Java التي تتولى منطق تطبيق الويب وتقنية الترميز HTML التي تتولى عرض المعلومات في المتصفح.

  • تتمثل عيوب الحل [1] القائم على الصفحة JSP في أنه يخلط بين كود HTML وكود Java داخل نفس الصفحة. لم نلاحظ ذلك في المثال الذي تمت معالجته والذي كان بسيطًا. ولكن إذا كان على [formulaire.jsp] التحقق من صحة معلمات [txtNom, txtAge] لطلب العميل، لكنا اضطررنا إلى وضع كود Java في الصفحة. وهذا يصبح غير قابل للإدارة بسرعة كبيرة.
  • تواجه الحلول القائمة على السيرفلت نفس المشكلة. على الرغم من وجود كود جافا فقط في الفئة، إلا أن هذه الفئة يجب أن تولد مستندًا. وهنا أيضًا، ما لم يكن المستند HTML بسيطًا، فإن إنشاؤه يصبح معقدًا ويكاد يكون من المستحيل صيانته.

سنتجنب خلط تقنيات Java و HTML من خلال اعتماد البنية التالية:

Image

  • يرسل المستخدم طلبه إلى السيرفلت. تقوم السيرفلت بمعالجته وبناء قيم المعلمات الديناميكية للصفحة JSP [formulaire.jsp] التي ستُستخدم لتوليد الاستجابة HTML للعميل. تشكل هذه القيم ما يُسمى بنموذج الصفحة JSP.
  • بمجرد الانتهاء من عملها، ستطلب السيرفلت من الصفحة JSP [formulaire.jsp] إنشاء الاستجابة HTML للعميل. وستزوده في الوقت نفسه بالعناصر التي تحتاجها الصفحة JSP لتوليد هذه الاستجابة، وهي العناصر التي تشكل نموذج الصفحة.

نستكشف الآن هذه البنية الجديدة.

3.7.1. البرنامج المساعد [ServletFormulaire2]

في البنية المذكورة أعلاه، ستسمى الخدمة [ServletFormulaire2]. وسيتم إنشاؤها في نفس المشروع [personne] كما في السابق، وكذلك جميع الخدمات القادمة:

Image

يتم الحصول على [ServletFormulaire2] أولاً عن طريق نسخ / لصق [ServletFormulaire] داخل Eclipse:

  • تحديد [ServletFormulaire.java] -> النقر بزر الماوس الأيمن -> نسخ
  • تحديد [istia.st.servlets.personne] -> النقر بزر الماوس الأيمن -> Paste -> تغيير الاسم إلى [ServletFormulaire2.java]

ثم نقوم بعد ذلك بتعديل كود [ServletFormulaire2] بالطريقة التالية:

package istia.st.servlets.personne;

import java.io.IOException;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@SuppressWarnings("serial")
public class ServletFormulaire2 extends HttpServlet {

    // معلمات المثيل
    private String defaultNom = null;

    private String defaultAge = null;

    // التشغيل
    public void init() {
        // يتم استرداد معلمات تهيئة السيرفلت
        ServletConfig config = getServletConfig();
        defaultNom = config.getInitParameter("defaultNom");
        if (defaultNom == null)
            defaultNom = "NNNNNNNNNNNNNNN";
        defaultAge = config.getInitParameter("defaultAge");
        if (defaultAge == null)
            defaultAge = "AAA";
    }

    // GET
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

        // استرداد معلمات النموذج
        String nom = request.getParameter("txtNom");
        if (nom == null) {
            nom = defaultNom;
        }
        String age = request.getParameter("txtAge");
        if (age == null) {
            age = defaultAge;
        }
        // عرض النموذج
        request.setAttribute("nom", nom);
        request.setAttribute("age", age);
        getServletContext().getRequestDispatcher("/formulaire2.jsp").forward(request, response);
    }

    // POST
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        // نمرر الأمر إلى GET
        doGet(request, response);
    }
}

لم يتغير سوى الجزء المتعلق بإنشاء الاستجابة HTTP (الأسطر 44-46):

  • السطر 46: يتم تكليف الصفحة JSP formulaire2.jsp بإنشاء الاستجابة. هذه الصفحة، التي لم يتم دراستها بعد، ستكون مسؤولة عن عرض المعلمات المستردة في طلب العميل، وهي الاسم (الأسطر 35-38) والعمر (الأسطر 39-42).
  • يتم وضع هاتين القيمتين في سمات الطلب [request]، المرتبطة بمفاتيح. تتم إدارة سمات الطلب كقاموس.
  • السطر 44: يتم وضع الاسم في الاستعلام المرتبط بالمفتاح "name"
  • السطر 45: يتم وضع العمر في الاستعلام المرتبط بالمفتاح "العمر"
  • السطر 46: يطلب عرض الصفحة JSP [formulaire2.jsp]. يتم تمرير المعلمات التالية إليها:
  • طلب العميل [request]، مما سيسمح للصفحة JSP بالوصول إلى سمات هذا الطلب التي تمت تهيئتها للتو بواسطة السيرفلت
  • الاستجابة [response] التي ستسمح للصفحة JSP بإنشاء الاستجابة HTTP للعميل

بمجرد كتابة الفئة [ServletFormulaire2]، يظهر كودها المُجمَّع في [build/classes]:

Image

3.7.2. الصفحة JSP [formulaire2.jsp]

يتم الحصول على الصفحة JSP formulaire2.jsp عن طريق نسخ / لصق الصفحة [formulaire.jsp]

Image

ثم تم تحويلها على النحو التالي:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<%
    // يتم استرداد القيم اللازمة للعرض
  String nom=(String)request.getAttribute("nom");
  String age=(String)request.getAttribute("age");  
%>

<html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
      <title>Personne - formulaire2</title>
  </head>
  <body>
      <center>
        <h2>Personne - formulaire2</h2>
      <hr>
      <form action="" method="post">
          <table>
            <tr>
              <td>Nom</td>
            <td><input name="txtNom" value="<%= nom %>" type="text" size="20"></td>
          </tr>
          <tr>
              <td>Age</td>
            <td><input name="txtAge" value="<%= age %>" type="text" size="3"></td>
          </tr>
        </table>
        <table>
            <tr>
              <td><input type="submit" value="Envoyer"></td>
            <td><input type="reset" value="Rétablir"></td>
            <td><input type="button" value="Effacer"></td>
          </tr>
        </table>
      </form>
    </center>
  </body>
</html>

لم تتغير سوى الأسطر 4-8 مقارنة بـ [formulaire.jsp]:

  • السطر 6: يسترد قيمة السمة المسماة "name" في الاستعلام [request]، وهي سمة تم إنشاؤها بواسطة الخدمة [ServletFormulaire2].
  • السطر 7: يفعل الشيء نفسه بالنسبة للسمة "age"

3.7.3. تكوين التطبيق

يتم تعديل ملف التكوين [web.xml] على النحو التالي:


<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4"
    xmlns="http://java.sun.com/xml/ns/j2ee"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>personne</display-name>
    <!--  ServletFormulaire -->
    <servlet>
        <servlet-name>formulairepersonne</servlet-name>
        <servlet-class>
            istia.st.servlets.personne.ServletFormulaire
        </servlet-class>
        <init-param>
            <param-name>defaultNom</param-name>
            <param-value>inconnu</param-value>
        </init-param>
        <init-param>
            <param-name>defaultAge</param-name>
            <param-value>XXXX</param-value>
        </init-param>
    </servlet>
    <!--  ServletFormulaire 2-->
    <servlet>
        <servlet-name>formulairepersonne2</servlet-name>
        <servlet-class>
            istia.st.servlets.personne.ServletFormulaire2
        </servlet-class>
        <init-param>
            <param-name>defaultNom</param-name>
            <param-value>inconnu</param-value>
        </init-param>
        <init-param>
            <param-name>defaultAge</param-name>
            <param-value>XXX</param-value>
        </init-param>
    </servlet>
    <!--  تعيين ServletFormulaire -->
    <servlet-mapping>
        <servlet-name>formulairepersonne</servlet-name>
        <url-pattern>/formulaire</url-pattern>
    </servlet-mapping>
    <!--  تعيين ServletFormulaire 2-->
    <servlet-mapping>
        <servlet-name>formulairepersonne2</servlet-name>
        <url-pattern>/formulaire2</url-pattern>
    </servlet-mapping>
    <!--  ملفات الصفحة الرئيسية -->
    <welcome-file-list>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>
</web-app>

لقد احتفظنا بما هو موجود وأضفنا:

  • الأسطر 22-36: قسم <servlet> لتعريف السيرفلت الجديد ServletFormulaire2
  • الأسطر 42-46: قسم <servlet-mapping> لربطه بـ URL /formulaire2

قم بتشغيل أو إعادة تشغيل خادم Tomcat إذا لزم الأمر. نطلب URL

http://localhost:8080/personne/formulaire2?txtNom=milou&txtAge=10:

Image

نحصل على نفس النتيجة السابقة، لكن بنية تطبيقنا أصبحت الآن أكثر وضوحًا: سيرفلت يحتوي على منطق التطبيق ويفوض صفحة JSP بإرسال الرد إلى العميل. سنعمل بهذه الطريقة من الآن فصاعدًا.