Skip to content

12. تطبيق الويب MVC [personne] – الإصدار 7

12.1. مقدمة

في هذا الإصدار، نفترض أنه قد تكون هناك متصفحات عملاء قامت بتعطيل:

  1. إعادة توجيه ملفات تعريف الارتباط التي يرسلها الخادم
  2. تنفيذ كود جافا سكريبت المضمن في الصفحات HTML المعروضة

ومع ذلك، نريد أن يتمكن هذا النوع من المتصفحات من استخدام تطبيقنا. النقطة 2 تعيدنا إلى الإصدار 2 من تطبيقنا، حيث تم استخدام جافا سكريبت بدءًا من الإصدار 3. كان الإصدار 2 يشغل التطبيق بدون جافا سكريبت، لذا تم حل النقطة 2.

قد يكون التعامل مع النقطة 1 صعبًا أو غير صعب. كانت النسخة 6 من تطبيقنا تعمل بدون ملفات تعريف الارتباط. من خلال دمج النسختين 2 و6، نحصل على النتيجة المطلوبة. سنضيف قيدًا إضافيًا: يجب أن يدير التطبيق جلسة عمل. هذا ليس قيدًا بلا معنى. في تطبيق يتعين على المستخدمين فيه المصادقة، يجب على الخادم حفظ زوج (المعرف / كلمة المرور) المستخدم لتجنيبه المصادقة في كل صفحة يطلبها.

استخدمنا حتى الآن ثلاثة حلول لتخزين المعلومات خلال التبادلات بين العميل والخادم:

  1. الجلسة
  2. ملفات تعريف الارتباط
  3. الحقول المخفية.

يمكن استبعاد الحل 2 لأن متصفح العميل قد يكون حظر استخدام ملفات تعريف الارتباط.

الحل 3 هو الحل الذي تمت دراسته سابقًا في الإصدار 6. لا يمكن استخدامه لأسباب أمنية. إذا تم تضمين الزوج (اسم المستخدم/كلمة المرور) في كل صفحة يتم إرسالها إلى المتصفح، فهذا يعني أنه يمر عبر الشبكة في كل تبادل بين العميل والخادم. وهذا ليس جيدًا لأمن التطبيق. يمكننا إذن التفكير في استخدام بروتوكول HTTPS الذي يشفر التبادلات بين العميل والخادم. لكن استخدامه لكل صفحة من صفحات التطبيق سيزيد من عبء الخادم.

قد نرغب في استبعاد الحل 1 لأنه يعتمد أيضًا على ملفات تعريف الارتباط. عند أول تبادل بين العميل والخادم، يرسل الخادم إلى العميل رمز جلسة عمل يقوم العميل بإرساله إلى الخادم في كل طلب جديد. بفضل هذا الرمز، سيتمكن الخادم من التعرف على العميل وتزويده بالمعلومات التي كان قد حفظها خلال تبادل سابق. يتم إرسال رمز الجلسة من قبل الخادم في ملف تعريف ارتباط. يمكن للمتصفح الذي لم يقم بتعطيل ملفات تعريف الارتباط أن يعيد إرسال ملف تعريف الارتباط هذا عند الطلبات التالية. إذا كان قد قام بتعطيل ملفات تعريف الارتباط، فإن هناك حلاً آخر متاحاً: يمكنه تضمين رمز الجلسة في عنوان URL الذي يطلبه. وهذا ما نراه الآن عند العودة إلى دراسة الملف [index.jsp] من الإصدار 4:


<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

<c:redirect url="/main"/>

نذكر أن السطر 5 أعلاه يعيد توجيه العميل إلى عنوان URL [/personne4/main?jsessionid=XX] حيث XX هو رمز الجلسة كما يظهر في لقطة الشاشة أدناه التي تم الحصول عليها بعد طلب عنوان URL [http://localhost:8080/personne4]:

Image

دعونا نلقي نظرة فاحصة على كيفية عمل العلامة <c:redirect> فيما يتعلق برمز الجلسة. لنأخذ متصفحًا يقبل ملفات تعريف الارتباط. فيما يلي، نقوم بتكوين متصفح Firefox:

Image

في [1]، نسمح بملفات تعريف الارتباط، وفي [2] نحذف الملفات الموجودة بالفعل من أجل البدء من حالة معروفة. ثم نطلب عنوان URL [http://localhost:8080/personne4]. ونحصل على الرد التالي:

Image

كان الطلب الأولي للعميل HTTP كما يلي:

1
2
3
4
5
6
7
8
9
GET /personne4/ HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

يجب ملاحظة أن العميل لا يرسل ملف تعريف ارتباط للجلسة. الإجابة HTTP المرسلة من الخادم هي التالية:

1
2
3
4
5
6
7
HTTP/1.x 302 Déplacé Temporairement
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=1ACA010A6BA28FB9E30A1D3184F574BC; Path=/personne4
Location: http://localhost:8080/personne4/main;jsessionid=1ACA010A6BA28FB9E30A1D3184F574BC
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Tue, 23 May 2006 09:10:05 GMT
  • السطر 1: يطلب الخادم من العميل إعادة التوجيه
  • السطر 3: يرسل الخادم رمز جلسة مرتبط بالسمة [JSESSIONID]
  • السطر 4: يحتوي عنوان URL لإعادة التوجيه على رمز الجلسة. وقد وضعته علامة <c:redirect> هناك لأن العميل لم يرسل ملف تعريف ارتباط للجلسة.

ثم أرسل المتصفح، الذي طُلب منه إعادة التوجيه، الطلب التالي:

GET /personne4/main;jsessionid=1ACA010A6BA28FB9E30A1D3184F574BC HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: JSESSIONID=1ACA010A6BA28FB9E30A1D3184F574BC
  • السطر 1: يطلب عنوان URL لإعادة التوجيه، بما في ذلك رمز الجلسة. ولهذا السبب يعرض المتصفح عنوان URL هذا في لقطة الشاشة.
  • السطر 10: يعيد المتصفح رمز الجلسة الذي أرسله إليه الخادم في التبادل السابق. هذا هو الأداء الطبيعي لملفات تعريف الارتباط عندما تكون مسموحة على متصفح العميل. إذا لم يكن الأمر كذلك، لا يتم إعادة إرسال ملفات تعريف الارتباط المستلمة.

رد الخادم بما يلي على هذا الطلب الثاني:

1
2
3
4
5
HTTP/1.x 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 2376
Date: Tue, 23 May 2006 09:10:05 GMT

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

الآن، باستخدام نفس المتصفح، لنطلب مرة أخرى عنوان URL [http://localhost:8080/personne4] عن طريق كتابته يدويًا. عندئذ نحصل على الصفحة التالية:

Image

نلاحظ أن عنوان URL المعروض بواسطة المتصفح لم يعد يحتوي على رمز الجلسة. لنلقِ نظرة على التبادل الأول بين العميل والخادم:

أرسل المتصفح الطلب التالي:

GET /personne4 HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: JSESSIONID=1ACA010A6BA28FB9E30A1D3184F574BC

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

أرسل الخادم الرد التالي:

1
2
3
4
5
HTTP/1.x 302 Déplacé Temporairement
Server: Apache-Coyote/1.1
Location: http://localhost:8080/personne4/
Transfer-Encoding: chunked
Date: Tue, 23 May 2006 09:24:39 GMT

يطلب من العميل إعادة التوجيه. ونظرًا لأنه تلقى رمز جلسة من العميل، فإنه يواصل هذه الجلسة ولا يرسل رمز جلسة جديدًا. وللسبب نفسه، لا تتضمن علامة <c:redirect> رمز الجلسة هذا في عنوان URL لإعادة التوجيه. ولهذا السبب لا يحتوي عنوان URL المعروض في لقطة الشاشة أعلاه على رمز جلسة.

سنستخلص من كل هذا القاعدة التالية: لا تضم علامة <c:redirect> رمز الجلسة في عنوان URL الخاص بإعادة التوجيه إلا إذا لم يرسل العميل الرأس HTTP:

Cookie: JSESSIONID=1ACA010A6BA28FB9E30A1D3184F574BC

تنطبق هذه القاعدة أيضًا على العلامة <c:url> التي سنلتقي بها لاحقًا.

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

Image

في [1]، نقوم بتعطيل ملفات تعريف الارتباط، وفي [2] نحذف الملفات الموجودة بالفعل من أجل البدء من حالة معروفة. ثم نطلب عنوان URL [http://localhost:8080/personne4]. ونحصل على الرد التالي:

Image

نحصل على نفس النتيجة السابقة. ومع ذلك، فإن التبادلات HTTP ليست متطابقة تمامًا:

GET /personne4/ HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

HTTP/1.x 302 Déplacé Temporairement
Server: Apache-Coyote/1.1
Set-Cookie: JSESSIONID=911B8156E0A9D32C2D256020C898E05C; Path=/personne4
Location: http://localhost:8080/personne4/main;jsessionid=911B8156E0A9D32C2D256020C898E05C
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 0
Date: Tue, 23 May 2006 09:39:55 GMT

GET /personne4/main;jsessionid=911B8156E0A9D32C2D256020C898E05C HTTP/1.1
Host: localhost:8080
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; fr; rv:1.8.0.3) Gecko/20060426 Firefox/1.5.0.3
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: fr-fr,fr;q=0.8,en;q=0.6,en-us;q=0.4,de;q=0.2
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive

HTTP/1.x 200 OK
Server: Apache-Coyote/1.1
Content-Type: text/html;charset=ISO-8859-1
Content-Length: 2376
Date: Tue, 23 May 2006 09:39:55 GMT
  • الأسطر 1-9: الطلب رقم 1 من المتصفح. لا يرسل ملف تعريف ارتباط للجلسة.
  • الأسطر 11-17: استجابة الخادم التي تطلب منه إعادة التوجيه إلى عنوان URL آخر. وهو يرسل ملف تعريف ارتباط للجلسة السطر 13: علامة <c:redirect> أدرجت الرمز المميز في عنوان URL لإعادة التوجيه في السطر 14.
  • الأسطر 19-27: الطلب رقم 2 من المتصفح. لا يعيد ملف تعريف الارتباط الخاص بالجلسة الذي أرسله إليه الخادم للتو لأن ملفات تعريف الارتباط الخاصة به معطلة.
  • الأسطر 29-33: استجابة الخادم. يمكن ملاحظة أنه على الرغم من أن المتصفح لم يرسل له ملف تعريف ارتباط الجلسة، إلا أنه لا يبدأ جلسة جديدة كما كان متوقعًا. ونلاحظ ذلك من خلال عدم إرساله لرأس HTTP [Set-Cookie] كما فعل في السطر 13. وهذا يعني أنه يواصل الجلسة السابقة. وقد تمكن من العثور عليها بفضل رمز الجلسة الموجود في عنوان URL الذي طلبه المتصفح في السطر 19.

تجدر الإشارة إلى أن الخادم يتتبع الجلسة من خلال استرداد رمز الجلسة الذي يرسله العميل، وذلك بطريقتين ممكنتين:

  • في الرأس HTTP [Set-Cookie] المرسلة من العميل
  • في عنوان URL الذي طلبه العميل

الآن، باستخدام نفس المتصفح، لنطلب مرة أخرى عنوان URL [http://localhost:8080/personne4] عن طريق كتابته يدويًا، كما تم فعله عندما كانت ملفات تعريف الارتباط مسموحة. عندئذ نحصل على الصفحة التالية:

Image

لدينا نتيجة مختلفة عن تلك التي تم الحصول عليها عندما كانت ملفات تعريف الارتباط مسموحة: رمز الجلسة موجود في عنوان URL المعروض بواسطة المتصفح. دعونا نوضح هذه النتيجة دون دراسة التبادلات HTTP التي حدثت:

[cookies autorisés]

  • عند الطلب الثاني لعنوان URL [http://localhost:8080/personne4]، أعاد متصفح العميل ملف تعريف الارتباط الخاص بالجلسة الذي تلقّاه من الخادم عند الطلب الأول لنفس عنوان URL. وبالتالي، لم تقم علامة <c:redirect> بتضمين رمز الجلسة في عنوان إعادة التوجيه.

[cookies inhibés]

  • عند الطلب الثاني لعنوان URL [http://localhost:8080/personne4]، لا يرسل متصفح العميل ملف تعريف الارتباط الخاص بالجلسة الذي تلقّاه من الخادم عند الطلب الأول لنفس عنوان URL هذا، لأن ملفات تعريف الارتباط الخاصة به معطلة. لذلك، تضم علامة <c:redirect> رمز الجلسة في عنوان إعادة التوجيه. ولهذا السبب نجده في لقطة الشاشة أعلاه.

تسمح العلامات <c:redirect> و <c:url> بتضمين رمز الجلسة في عناوين URL. وهذا هو الحل المقترح هنا.

12.2. مشروع Eclipse

لإنشاء مشروع Eclipse [mvc-personne-07] لتطبيق الويب [/personne7]، سنقوم بنسخ مشروع [mvc-personne-06] باتباع الإجراء الموضح في الفقرة 6.2.

12.3. تكوين تطبيق الويب [personne7]

الملف web.xml لتطبيق /personne7 هو كما يلي:


<?xml version="1.0" encoding="UTF-8"?>
...
    <display-name>mvc-personne-07</display-name>
...

هذا الملف مطابق لملف الإصدار السابق باستثناء السطر 3 حيث تغير اسم عرض تطبيق الويب إلى [mvc-personne-07]. لا تتغير الصفحة الرئيسية [index.jsp].


...
<c:redirect url="/do/formulaire"/>

12.4. رمز طرق العرض

تعود طرق العرض [formulaire, réponse, erreurs] إلى ما كانت عليه في الإصدار 2، c.a.d. بدون جافا سكريبت. ومع ذلك، فإنها تحتفظ بعلامات JSTL من الإصدارات الأخيرة.

12.4.1. طريقة العرض [formulaire]

Image

تمت إزالة الأزرار المرتبطة برمز جافا سكريبت.

[formulaire.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">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

<html>
  <head>
    <title>Personne - formulaire</title>
  </head>
  <body>
    <center>
      <h2>Personne - formulaire</h2>
      <hr>
      <form name="frmPersonne" action="<c:url value="validationFormulaire"/>" 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>
          <tr>
        </table>
        <table>
          <tr>
            <td><input type="submit" name="bouton" value="Envoyer"></td>
            <td><input type="reset" value="Rétablir"></td>
            <td><input type="submit" name="bouton" value="Effacer"></td>
          </tr>
        </table>
      </form>
    </center>
  </body>
</html>
  • السطر 14: يتم كتابة عنوان URL الهدف لـ POST باستخدام العلامة <c:url> بحيث يكون رمز الجلسة موجودًا فيه في حالة ما إذا كان العميل متصفحًا لا يرسل رأس HTTP [Cookie].
  • يحتوي النموذج على زرين من النوع [submit]: [Envoyer] (السطر 28) و [Effacer] (السطر 30). يحمل الزران نفس الاسم: bouton. عند POST، سيرسل المتصفح المعلمة:
  • button=Send إذا تم إرسال POST بواسطة الزر [Send]
  • button=حذف إذا تم إرسال POST بواسطة الزر [حذف]

وهذا المعامل هو الذي سيساعدنا في تحديد الإجراء المحدد الذي يجب القيام به، حيث أصبح عنوان URL [/do/validationFormulaire] يمثل الآن إجراءين منفصلين.

12.4.2. العرض [réponse]

Image

[réponse.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">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Personne - réponse</h2>
    <hr>
    <table>
        <tr>
          <td>Nom</td>
        <td>${nom}</td>
      </tr>
        <tr>
          <td>Age</td>
        <td>${age}</td>
      </tr>
    </table>      
    <br>
    <a href="<c:url value="retourFormulaire"/>">${lienRetourFormulaire}</a>
  </body>
</html>

  • السطر 24: يتم كتابة عنوان URL الهدف لـ HREF باستخدام العلامة <c:url> بحيث يكون رمز الجلسة موجودًا فيه في حالة ما إذا كان العميل متصفحًا لا يرسل رأس HTTP [Cookie].

12.4.3. عرض [erreurs]

Image

[erreurs.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">
<%@ taglib uri="/WEB-INF/c.tld" prefix="c" %>

<html>
    <head>
      <title>Personne</title>
  </head>
  <body>
      <h2>Les erreurs suivantes se sont produites</h2>
    <ul>
            <c:forEach var="erreur" items="${erreurs}">
                <li>${erreur}</li>
            </c:forEach>
    </ul>
    <br>
    <a href="<c:url value="retourFormulaire"/>">${lienRetourFormulaire}</a>
  </body>
</html>

  • السطر 18: يتم كتابة عنوان URL الهدف لـ HREF باستخدام العلامة <c:url> بحيث يكون رمز الجلسة موجودًا فيه في حالة ما إذا كان العميل متصفحًا لا يرسل رأس HTTP [Cookie].

يُطلب من القارئ اختبار هذه العروض الجديدة وفقًا للمبدأ الذي تمت مناقشته في الإصدارات السابقة.

12.5. وحدة التحكم [ServletPersonne]

وحدة التحكم [ServletPersonne] لتطبيق الويب [/personne7] هي كما يلي:

package istia.st.servlets.personne;

...

@SuppressWarnings("serial")
public class ServletPersonne extends HttpServlet {
    // معلمات المثيل
    private String urlErreurs = null;
    private ArrayList erreursInitialisation = new ArrayList<String>();
    private String[] paramètres={"urlFormulaire","urlReponse","lienRetourFormulaire"};
    private Map params=new HashMap<String,String>();

    // init
    @SuppressWarnings("unchecked")
    public void init() throws ServletException {
...
    }

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

...
        // يتم استرداد طريقة إرسال الطلب
        String méthode=request.getMethod().toLowerCase();
        // استرداد الإجراء المطلوب تنفيذه
        String action=request.getPathInfo();
...
        if(méthode.equals("post") && action.equals("/validationFormulaire")){
            // التحقق من صحة نموذج الإدخال
            doValidationFormulaire(request,response);
            return;
        }
        if(méthode.equals("get") && action.equals("/retourFormulaire")){
            // العودة إلى نموذج الإدخال
            doRetourFormulaire(request,response);
            return;
        }
        // حالات أخرى
        doInit(request,response);
    }

    // عرض النموذج فارغًا
    void doInit(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
...
    }

    // عرض النموذج المملوء مسبقًا
    void doRetourFormulaire(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        // يتم عرض النموذج
        getServletContext().getRequestDispatcher((String)params.get("urlFormulaire")).forward(
                request, response);
        return;
    }

    // عرض نموذج فارغ
    void doEffacer(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException{
        // يتم إعداد نموذج النموذج
        HttpSession session = request.getSession(true);        
        session.setAttribute("nom", "");
        session.setAttribute("age", "");
        // عرض النموذج
        getServletContext().getRequestDispatcher((String)params.get("urlFormulaire")).forward(
                request, response);
        return;
    }

    // التحقق من صحة النموذج
    void doValidationFormulaire(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException{
        // استرداد الزر الذي تسبب في POST
        String bouton = request.getParameter("bouton").toLowerCase();
        // المعالجة وفقًا للزر الذي تسبب في POST
        if(bouton==null){
            doInit(request,response);
            return;
        }
        if("envoyer".equals(bouton)){
            doEnvoyer(request,response);
            return;
        }
        if("effacer".equals(bouton)){
            doEffacer(request,response);
            return;
        }
    }

    // التحقق من صحة النموذج
    void doEnvoyer(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException{
        // يتم استرداد المعلمات
        String nom = request.getParameter("txtNom");
        String age = request.getParameter("txtAge");
        // التي يتم حفظها في الجلسة
        HttpSession session = request.getSession(true);        
        session.setAttribute("nom", nom);
        session.setAttribute("age", age);
        // يتم وضع رابط العودة إلى النموذج في قالب العروض [réponse, erreurs]
        request.setAttribute("lienRetourFormulaire", (String)params.get("lienRetourFormulaire"));    
        // التحقق من المعلمات
        ArrayList<String> erreursAppel = new ArrayList<String>();
    ...
        // هل توجد أخطاء في المعلمات؟
        if (erreursAppel.size() != 0) {
            // يتم إرسال صفحة الأخطاء
            request.setAttribute("erreurs", erreursAppel);
            getServletContext().getRequestDispatcher(urlErreurs).forward(
                    request, response);
            return;
        }
        // الإعدادات صحيحة - يتم إرسال صفحة الرد
        getServletContext().getRequestDispatcher((String)params.get("urlReponse")).forward(request,
                response);
        return;
    }

    // إرسال
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
...
    }
}
  • السطر 35: يتم تنفيذ الإجراء [/retourFormulaire] بواسطة GET وليس بواسطة POST كما في الإصدار السابق.
  • الأسطر 70-87: يتم تنفيذ الإجراء [/validationFormulaire] بواسطة POST الذي يتم تشغيله بالنقر فوقأحد الأزرار [Envoyer] أو [Effacer] في العرض [formulaire]. تعالج الطريقة [doValidationFormulaire] هاتين الحالتين بواسطة طريقتين مختلفتين.
  • الأسطر 90-103: الطريقة [doEnvoyer] تتوافق مع الطريقة [doValidationFormulaire] في الإصدار السابق. يتم وضع البيانات المدخلة في الجلسة (الأسطر 96-98) بينما في الإصدار السابق كانت توضع في الاستعلام.
  • الأسطر 58-67: يجب أن تعرض الطريقة الجديدة [doEffacer] نموذجًا فارغًا. يمكننا الاستعانة بالطريقة [doInit] التي تقوم بهذه المهمة بالفعل. هنا، نستغل الفرصة أيضًا لمسح عناصر [nom, age] من الجلسة حتى تظل تعكس الحالة الأخيرة للنموذج.
  • الأسطر 50-55: تطلب عرض طريقة العرض [formulaire] دون تهيئة واضحة لنموذج طريقة العرض هذه. يتكون هذا النموذج في الواقع من عناصر [nom, age] الموجودة بالفعل في الجلسة. لا داعي لفعل المزيد.

12.6. الاختبارات

قم بتشغيل أو إعادة تشغيل Tomcat بعد دمج مشروع Eclipse [personne-mvc-07] فيه، ثم اطلب عنوان URL [http://localhost:8080/personne7] باستخدام متصفح تم تعطيل ملفات تعريف الارتباط فيه وحذف الملفات الموجودة بالفعل. نحصل على الرد التالي:

Image

الرمز المصدري الذي يتلقاه المتصفح هو التالي:

1
2
3
<form name="frmPersonne" action="validationFormulaire;jsessionid=9D4CC83FEFB51AE78B1FD71EC66F9EF3" method="post">
...
</form>

السطر 1، رمز الجلسة موجود في عنوان URL الهدف لـ POST.

لنملأ النموذج ونضغط على زر "إرسال":

Image

الرمز المصدري الذي يتلقاه المتصفح هو التالي:

1
2
3
4
...
    <br>
    <a href="retourFormulaire;jsessionid=9D4CC83FEFB51AE78B1FD71EC66F9EF3">Retour au formulaire</a>
  </body>

السطر 3، رمز الجلسة موجود في عنوان URL الهدف للرابط.