Skip to content

3. مبانی توسعه وب با جاوا

اکنون به توسعهٔ برنامه‌های وب پویا، c.a.d – برنامه‌هایی که صفحات HTML ارسال‌شده به کاربر توسط برنامه‌ها تولید می‌شوند – می‌پردازیم.

3.1. ایجاد یک پروژه وب در اکلیپس

ما قصد داریم اولین برنامه وب خود را با استفاده از Eclipse/Tomcat توسعه دهیم. رویکردی مشابه با آنچه برای ایجاد یک برنامه وب بدون Eclipse استفاده می‌شود را دنبال خواهیم کرد. پس از راه‌اندازی Eclipse، یک پروژه جدید ایجاد می‌کنیم:

Image

که آن را به‌عنوان یک پروژه وب پویا تعریف می‌کنیم:

Image

در صفحه اول جادوگر ایجاد، نام پروژه [1] و مکان آن [2] را مشخص می‌کنیم:

Image

در صفحه دوم جادوگر، مقادیر پیش‌فرض را می‌پذیریم:

Image

صفحه نهایی جادوگر از ما می‌خواهد که زمینهٔ برنامه را [3] تعریف کنیم:

Image

پس از تأیید توسط [Finish]، اکلیپس به سایت [http://java.sun.com] متصل می‌شود تا برخی اسناد را که می‌خواهد در حافظه پنهان ذخیره کند، بازیابی نماید تا از ترافیک شبکه غیرضروری جلوگیری کند. سپس یک درخواست تأیید مجوز نمایش داده می‌شود:

Image

ما این را می‌پذیریم. اکلیپس پروژه وب را ایجاد می‌کند. برای مشاهده آن، از محیطی به نام «منظره» (perspective) استفاده می‌کند که با محیط مورد استفاده برای یک پروژه استاندارد جاوا متفاوت است:

Image

منظره‌ای که با یک پروژه وب مرتبط است، J2EE است. ما آن را می‌پذیریم تا نگاهی به آن بیندازیم… نتیجه به شرح زیر است:

Image

منظر J2EE در واقع برای پروژه‌های وب ساده، غیرضروری و پیچیده است. در این مورد، منظر جاوا کافی است. برای انتخاب آن، از گزینه [Window -> Open perspective -> Java] استفاده می‌کنیم:

Image

src: حاوی کد جاوا برای کلاس‌های برنامه و همچنین فایل‌هایی خواهد بود که باید در Classpath برنامه گنجانده شوند.

build/classes (نمایش داده نشده): حاوی فایل‌های .class کلاس‌های کامپایل‌شده و همچنین کپی تمام فایل‌های غیر-.java موجود در src خواهد بود. یک برنامه وب اغلب از فایل‌های به‌اصطلاح «منبع» (resource) استفاده می‌کند که باید در Classpath و c.a.d برنامه گنجانده شوند. تمام دایرکتوری‌هایی که توسط JVM هنگام ارجاع برنامه به یک کلاس، چه در زمان کامپایل و چه در زمان اجرا، اسکن می‌شوند. اکلیپس اطمینان حاصل می‌کند که دایرکتوری build/classes بخشی از برنامه وب را تشکیل دهد. فایل‌های «منبع» در دایرکتوری src قرار می‌گیرند، زیرا اکلیپس به طور خودکار آن‌ها را به 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

ایکلپس تلاش خواهد کرد سند XML را با استفاده از فایل .xsd مشخص‌شده در ویژگی [xsi:schemaLocation] تگ آغازین <web-app> اعتبارسنجی کند. برای این کار، یک اتصال شبکه‌ای برقرار خواهد کرد. اگر رایانه شما در یک شبکه خصوصی قرار دارد، باید به اکلپس بگویید که از کدام ماشین برای دسترسی به اینترنت از طریق شبکه خصوصی استفاده کند، که به آن پروکسی HTTP گفته می‌شود. این کار با استفاده از گزینه [Window -> Preferences -> Internet] انجام می‌شود:

Image

کادر (۱) را اگر در یک شبکه خصوصی هستید، علامت بزنید. در (۲)، نام ماشینی را که میزبان پروکسی HTTP است وارد کنید و در (۳)، پورت گوش‌دادن آن را وارد کنید. در نهایت، در (۴)، ماشین‌هایی را که نباید از پروکسی استفاده کنند مشخص کنید – این‌ها ماشین‌هایی در همان شبکه خصوصی هستند که ماشین شما روی آن کار می‌کند.

اکنون فایل [index.html] را برای صفحه اصلی ایجاد خواهیم کرد.

3.2. ایجاد یک صفحهٔ اصلی

روی پوشه [WebContent] کلیک راست کرده و گزینه [New -> Other] را انتخاب کنید:

Image

ما نوع [HTML] را انتخاب می‌کنیم و [Next] را به

Image

در بالا، پوشهٔ والد [WebContent] را در (۱) یا (۲) انتخاب می‌کنیم، سپس نام فایلی را که باید ایجاد شود در (۳) مشخص می‌کنیم. پس از انجام این کار، به صفحهٔ بعدی جادوگر می‌رویم:

Image

با انتخاب (۱)، می‌توانیم یک فایل HTML را که از جزئیات (۲) از پیش پر شده است، ایجاد کنیم. اگر (۱) را انتخاب نکنیم، یک فایل خالی HTML ایجاد می‌کنیم. ما تیک (۱) را می‌زنیم تا بتوانیم از یک قالب کد بهره‌مند شویم. جادوگر را با [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) نمایش داده می‌شوند. می‌توانید آن‌ها را از طریق (2) روی سرور Tomcat ثبت کنید. برنامه‌های وب ثبت‌شده در سرور Tomcat در (4) ظاهر می‌شوند. می‌توانید آن‌ها را با استفاده از (3) لغو ثبت کنید. بیایید پروژه [personne] را ثبت کنیم:

Image

سپس با [Finish] جادوگر ثبت‌نام را تکمیل کنید. نمای [Servers] نشان می‌دهد که پروژه [personne] در Tomcat ثبت شده است:

Image

اکنون، سرور Tomcat را راه‌اندازی کنیم:

بیایید مرورگر وب را باز کنیم:

Image

سپس URL [http://localhost:8080/personne] را درخواست کنید. این URL ریشهٔ برنامهٔ وب است. هیچ سندی درخواست نشده است. در این حالت، صفحهٔ اصلی برنامه نمایش داده می‌شود. اگر این صفحه وجود نداشته باشد، خطایی گزارش می‌شود. در اینجا، صفحهٔ اصلی وجود دارد. این همان فایلی است که قبلاً با نام [index.html] ایجاد کردیم. نتیجه به شرح زیر است:

Image

این همان چیزی است که انتظار می‌رفت. اکنون، بیایید از یک مرورگر خارج از اکلیپس استفاده کنیم و همان URL را درخواست کنیم:

Image

بنابراین، اپلیکیشن وب [personne] نیز در خارج از Eclipse شناسایی می‌شود.

3.4. ایجاد یک فرم HTML

اکنون یک سند ایستا HTML، [formulaire.html]، را در پوشه [personne] ایجاد خواهیم کرد:

Image

برای ایجاد آن، مراحل توصیف‌شده در بخش ۳.۲، صفحهٔ ۳۳ را دنبال کنید. محتوای آن به شرح زیر خواهد بود:


<!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
خط ۱۴
نام ورود
2
<input type="text">
txtAge
خط ۱۸
سن را وارد کنید
3
<input type="submit">
 
خط ۲۳
ارسال مقادیر واردشده به سرور در آدرس /person1/main
4
<input type="reset">
 
خط ۲۴
تا صفحه را به حالتی بازگرداند که در ابتدا توسط مرورگر دریافت شده بود
5
<input type="button">
 
خط ۲۵
برای پاک کردن محتویات فیلدهای ورودی [1] و [2]

بیایید سند را در پوشه <person>/WebContent ذخیره کنیم. در صورت لزوم Tomcat را راه‌اندازی کنید. با استفاده از یک مرورگر، صفحه URL http://localhost:8080/personne/formulaire.html را درخواست کنید:

Image

معماری کلاینت/سرور این برنامهٔ پایه‌ای به شرح زیر است:

Image

سرور وب بین کاربر و برنامه وب قرار دارد و در اینجا نشان داده نشده است. [formulaire.html] یک سند ایستا است که برای هر درخواست مشتری همان محتوا را بازمی‌گرداند. برنامه‌نویسی وب با هدف تولید محتوایی متناسب با درخواست مشتری انجام می‌شود. این محتوا سپس توسط یک برنامه تولید می‌شود. یک راه‌حل ممکن استفاده از JSP (صفحه سرور جاوا) به جای فایل ایستا HTML است. این همان چیزی است که اکنون در حال بررسی آن هستیم.

3.5. ایجاد یک صفحه JSP


بخش‌های [ref1]: فصل ۱، فصل ۲: ۲.۲، ۲.۲.۱، ۲.۲.۲، ۲.۲.۳، ۲.۲.۴


معماری کلاینت/سرور قبلی به شرح زیر تغییر می‌یابد:

Image

یک صفحه JSP نسخه‌ای پیکربندی‌شده از یک صفحه HTML است. برخی از عناصر صفحه تنها در زمان اجرا مقادیر خود را دریافت می‌کنند. این مقادیر توسط برنامه محاسبه می‌شوند. بنابراین ما یک صفحه پویا داریم: درخواست‌های متوالی برای صفحه ممکن است به پاسخ‌های متفاوتی منجر شوند. در اینجا، ما به صفحه HTML که توسط مرورگر کلاینت نمایش داده می‌شود، به عنوان «پاسخ» اشاره می‌کنیم. در نهایت، همیشه یک سند HTML است که مرورگر دریافت می‌کند. این سند HTML توسط وب‌سرور از صفحه JSP تولید می‌شود. این سند به عنوان یک الگو عمل می‌کند. عناصر پویا آن در زمان تولید سند HTML با مقادیر واقعی خود جایگزین می‌شوند.

برای ایجاد یک صفحه JSP، روی پوشه [WebContent] کلیک راست کرده و سپس گزینه [New -> Other] را انتخاب می‌کنیم:

Image

نوع [JSP] را انتخاب کرده و به [Next] ادامه می‌دهیم ->

Image

در بالا، پوشهٔ والد [WebContent] را در (۱) یا (۲) انتخاب می‌کنیم، سپس نام فایلی را که باید ایجاد شود در (۳) مشخص می‌کنیم. پس از انجام این کار، به صفحهٔ بعدی جادوگر می‌رویم:

Image

با انتخاب (۱)، می‌توانیم یک فایل JSP را که از قبل با داده‌های (۲) پر شده است، ایجاد کنیم. اگر (۱) را انتخاب نکنیم، یک فایل خالی JSP ایجاد می‌کنیم. ما تیک (۱) را می‌زنیم تا بتوانیم از یک قالب کد بهره‌مند شویم. جادوگر را با [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>

خط ۱ نشان می‌دهد که ما با صفحه‌ای به نام 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>

این سند که در ابتدا ایستا بود، اکنون با معرفی کد جاوا پویا شده است. برای این نوع سند، ما همیشه به شرح زیر عمل خواهیم کرد:

  • ما کد جاوا را در همان ابتدای سند برای بازیابی پارامترهای مورد نیاز جهت نمایش سند درج می‌کنیم. این پارامترها اغلب در شیء `request` یافت می‌شوند. این شیء نمایانگر درخواست کلاینت است. این درخواست ممکن است از چندین servlet و صفحات JSP عبور کند که ممکن است آن را غنی کرده باشند. در اینجا، این درخواست مستقیماً از مرورگر می‌رسد.
  • کد HTML در ادامه آمده است. این کد معمولاً به سادگی متغیرهایی را که قبلاً در کد جاوا با استفاده از برچسب‌های <%= variable %> محاسبه شده‌اند، نمایش می‌دهد. توجه داشته باشید که در اینجا علامت = بلافاصله پس از علامت % نوشته می‌شود. این یک علت رایج خطاها است.

این سند پویا چه کاری انجام می‌دهد؟

  • خطوط ۶–۹: دو پارامتر با نام‌های [txtNom] و [txtAge] را از درخواست بازیابی می‌کند و مقادیر آن‌ها را به متغیرهای [nom] (خط ۶) و [age] (خط ۸). اگر نتواند پارامترها را پیدا کند، مقادیر پیش‌فرض را به متغیرهای مربوطه اختصاص می‌دهد.
  • این کد HTML (خطوط 25 و 29) مقادیر دو متغیر [nom, age] را نمایش می‌دهد.

بیایید یک تست اولیه انجام دهیم. در صورت لزوم Tomcat را راه‌اندازی کنید، سپس با استفاده از یک مرورگر درخواست 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]: فصل ۱، فصل ۲: ۲.۱، ۲.۱.۱، ۲.۱.۲، ۲.۳.۱


در نسخه قبلی، درخواست کلاینت توسط صفحه‌ای به نام JSP پردازش می‌شد. هنگامی که این صفحه برای اولین بار فراخوانی می‌شود، سرور وب—در این مورد، Tomcat—یک کلاس جاوا از این صفحه ایجاد کرده و آن را کامپایل می‌کند. این نتیجه کامپایل است که در نهایت درخواست کلاینت را پردازش می‌کند. کلاسی که از صفحه JSP تولید می‌شود، یک سرولت است زیرا رابط [javax.Servlet] را پیاده‌سازی می‌کند:

Image

درخواست کلاینت می‌تواند توسط هر کلاسی که این رابط را پیاده‌سازی می‌کند، پردازش شود. اکنون چنین کلاسی را ایجاد خواهیم کرد: ServletFormulaire. معماری کلاینت/سرور قبلی به شکل زیر تغییر می‌یابد:

Image

در معماری مبتنی بر صفحه JSP، سند HTML که به کلاینت ارسال می‌شود، توسط وب سرور از صفحه JSP که به عنوان الگو عمل می‌کرد، تولید شد. در اینجا، سند HTML که به کلاینت ارسال می‌شود، به‌طور کامل توسط سرولت تولید خواهد شد.

3.6.1. ایجاد سرولت

در اکلیپس، روی پوشه [src] کلیک راست کرده و گزینه ایجاد کلاس را انتخاب کنید:

Image

سپس ویژگی‌های کلاس مورد نظر را تعریف کنید:

Image

در (۱)، نام یک پکیج را وارد کنید؛ در (۲)، نام کلاسی را که قرار است ایجاد شود وارد کنید. این کلاس باید از کلاسی که در (۳) مشخص شده است ارث ببرد. لازم نیست نام کامل این کلاس را خودتان تایپ کنید. دکمه (۴) دسترسی به کلاس‌های موجود در پکیج Classpath وب‌اپلیکیشن را فراهم می‌کند:

Image

در (۱)، نام کلاسی را که به دنبال آن هستید وارد کنید. در (۲)، کلاس‌هایی را در Classpath مشاهده خواهید کرد که نامشان حاوی رشته وارد شده در (۱) است.

پس از اعتبارسنجی توسط جادوگر ایجاد، پروژه وب [personne] به شرح زیر اصلاح می‌شود:

Image

کلاس [ServletFormulaire] با یک اسکلت کد ایجاد شده است:

Image

اسکرین‌شات بالا نشان می‌دهد که اکلیپس یک [warning] را در خط اعلام کلاس علامت‌گذاری می‌کند. بیایید روی آیکون (لامپ) که این [warning] را نشان می‌دهد کلیک کنیم:

Image

پس از کلیک بر روی (۱)، راه‌حل‌هایی برای حذف [warning] در (۲) پیشنهاد می‌شوند. انتخاب یکی از آن‌ها باعث می‌شود که تغییر کد حاصل از این انتخاب در (۳) نمایش داده شود.

جاوا ۱.۵ تغییراتی را در زبان جاوا معرفی کرد و چیزی که در نسخه قبلی صحیح بود، اکنون ممکن است مشمول [warnings] باشد. این موارد نشان‌دهنده خطاهایی نیستند که از کامپایل شدن کلاس جلوگیری کنند. آنها برای جلب توجه توسعه‌دهنده به بخش‌هایی از کد که می‌توان آنها را بهبود بخشید، وجود دارند. خطای [warning] که در اینجا نشان داده شده است، پیشنهاد می‌کند که یک کلاس باید دارای شماره نسخه باشد. این شماره برای سریالی‌سازی/دسریالی‌سازی اشیاء، c.a.d، استفاده می‌شود. هنگامی که یک شیء جاوا .class در حافظه نیاز به تبدیل شدن به یک دنباله از بیت‌ها دارد که به صورت متوالی در یک جریان نوشتن ارسال می‌شوند، یا برعکس، هنگامی که یک شیء جاوا .class در حافظه نیاز به ایجاد شدن از یک دنباله از بیت‌ها دارد که به صورت متوالی از یک جریان خواندن خوانده شده‌اند. تمام این‌ها از دغدغه‌های فعلی ما دور است. بنابراین، با انتخاب راه‌حل [Add @SuppressWarnings ...]، به کامپایلر دستور می‌دهیم که این هشدار را نادیده بگیرد. کد در این صورت به شکل زیر درمی‌آید:

Image

دیگر هیچ [warning] وجود ندارد. خط اضافه شده «annotation» نامیده می‌شود، مفهومی که در جاوا نسخهٔ ۱.۵ معرفی شد. ما این کد را در مرحله‌ای بعدی تکمیل خواهیم کرد.

3.6.2. مسیر کلاس یک پروژه اکلیپس

Classpath یک برنامهٔ جاوا، مجموعه‌ای از دایرکتوری‌ها و archives.jar است که هنگام کامپایل توسط کامپایلر یا هنگام اجرای آن توسط JVM جستجو می‌شوند. این دو Classpath لزوماً یکسان نیستند، زیرا برخی کلاس‌ها تنها در زمان اجرا مورد نیاز هستند و نه در زمان کامپایل. هم کامپایلر جاوا و هم JVM دارای آرگومانی هستند که امکان مشخص کردن Classpath از برنامه را برای کامپایل یا اجرا فراهم می‌کند. اکلپس، به روشی که تا حد زیادی برای کاربر شفاف است، ساخت و ارسال این آرگومان به JVM را مدیریت می‌کند.

چگونه می‌توان اجزای Classpath را برای یک پروژه اکلیپس پیدا کرد؟ با استفاده از گزینه [<projet> / Build Path / Configure Build Path]:

Image

سپس wizard پیکربندی زیر را مشاهده می‌کنیم:

Image

زبانه‌ی (۱) [Libraries] به شما امکان می‌دهد فهرست آرشیوهای .jar را که بخشی از Classpath برنامه‌اند، تعریف کنید. این آرشیوها هنگام درخواست یک کلاس توسط JVM جستجو می‌شوند. دکمه‌های [2] و [3] به شما امکان می‌دهند آرشیوها را به Classpath اضافه کنید. دکمه [2] به شما امکان می‌دهد آرشیوهایی را که در پوشه‌های پروژه‌های مدیریت‌شده توسط Eclipse قرار دارند انتخاب کنید، در حالی که دکمه [3] به شما امکان می‌دهد هر آرشیویی را از سیستم فایل کامپیوتر انتخاب کنید.

در بالا، سه کتابخانه نمایش داده شده‌اند:

  • [JRE System Library]: کتابخانهٔ پایه برای پروژه‌های جاوا در Eclipse:

Image

  • [Tomcat v5.5 runtime]: کتابخانه‌ای که توسط سرور Tomcat ارائه می‌شود. این کتابخانه شامل کلاس‌های مورد نیاز برای توسعه وب است. این کتابخانه در هر پروژه وب اکلیپس که با سرور 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]: فصل ۲: ۲.۳، ۲.۳.۱، ۲.۳.۲، ۲.۳.۳، ۲.۳.۴


فایل [WEB-INF/web.xml] برای پیکربندی برنامه وب استفاده می‌شود:

Image

این فایل برای پروژه [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-list>
</web-app>

این فایل صرفاً وجود یک صفحهٔ اصلی را (خط ۸) نشان می‌دهد. ما آن را به‌روزرسانی می‌کنیم تا اعلام کند:

  • وجود سرولتی به نام [ServletFormulaire]
  • فایل‌های URL که توسط این سرولت پردازش می‌شوند
  • پارامترهای راه‌اندازی سرولت

فایل web.xml در اپلیکیشن «person» ما به شرح زیر خواهد بود:


<?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>

نکات کلیدی این فایل پیکربندی به شرح زیر است:

  • خطوط ۷–۲۴ مربوط به وجود سروِلت [ServletFormulaire] هستند
  • خطوط ۷–۲۰: یک سروِلت بین تگ‌های <servlet> و </servlet> پیکربندی می‌شود. یک برنامه ممکن است شامل چندین سروِلت باشد و بنابراین به همان تعداد بخش‌های پیکربندی <servlet>...</servlet> داشته باشد.
  • خط ۸: تگ <servlet-name> یک نام به سرولت اختصاص می‌دهد – این می‌تواند هر چیزی باشد
  • خطوط ۹–۱۱: تگ <servlet-class> نام کامل کلاس متناظر با سرولت را مشخص می‌کند. تام‌کت این کلاس را در دایرکتوری Classpath پروژه وب [personne] جستجو خواهد کرد. آن را در [build/classes] پیدا خواهد کرد:

Image

  • خطوط ۱۲–۱۵: تگ <init-param> برای ارسال پارامترهای پیکربندی به سرویس‌لت استفاده می‌شود. این پارامترها معمولاً در متد init سرویس‌لت خوانده می‌شوند، زیرا پارامترهای پیکربندی آن باید به محض بارگذاری اولیه مشخص باشند.
  • خطوط ۱۳–۱۴: تگ <param-name> نام پارامتر و <param-value> مقدار آن را مشخص می‌کند.
  • خطوط ۱۲–۱۵ یک پارامتر به نام [defaultNom,"inconnu"] را تعریف می‌کنند و خطوط ۱۶–۱۹ یک پارامتر به نام [defaultAge,"XXX"] را تعریف می‌کنند
  • خطوط ۲۱–۲۴: تگ <servlet-mapping> برای مرتبط ساختن یک سرولت (servlet-name) با یک قالب URL (url-pattern) استفاده می‌شود. در اینجا، الگو ساده است. این مشخص می‌کند که هر زمان یک URL به شکل /form باشد، باید از servlet «formulairepersonne»، c.a.d، استفاده شود. کلاس [istia.st.servlets.ServletFormulaire] (خطوط 8–11). بنابراین تنها یک URL توسط servlet [formulairepersonne] پذیرفته می‌شود.

3.6.4. کد برای servlet [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;

     //init
    public void init() {
         //پارامترهای راه‌اندازی servlet را بازیابی می‌کند
        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 آن (خط ۲۰) فراخوانی می‌شود. این تنها باری است که فراخوانی می‌شود.
  • اگر سروِلت از طریق متد HTTP GET فراخوانی شده باشد، متد doGet (خط ۳۲) برای پردازش درخواست مشتری فراخوانی می‌شود.
  • اگر سروِلت توسط متد HTTP POST فراخوانی شده باشد، متد doPost (خط ۸۲) برای پردازش درخواست کلاینت فراخوانی می‌شود.

متد init** در اینجا برای بازیابی مقادیر پارامترهای راه‌اندازی با نام‌های «defaultNom» و «defaultAge» در داخل [web.xml] استفاده می‌شود. متد init** که هنگام بارگذاری اولیه سرولت اجرا می‌شود، مکان مناسبی برای بازیابی محتویات فایل [web.xml] است.

  • خط ۲۲: پیکربندی پروژه وب [config] بازیابی می‌شود. این شیء محتوای فایل برنامه [WEB-INF/web.xml] را منعکس می‌کند.
  • خط ۲۳: از این پیکربندی، مقدار نوع String برای پارامتر با نام «defaultNom» بازیابی می‌شود. این پارامتر حاوی نام یک شخص خواهد بود. اگر این پارامتر وجود نداشته باشد، مقدار null بازگردانده می‌شود.
  • خطوط ۲۴–۲۵: اگر پارامتر با نام «defaultNom» وجود نداشته باشد، مقدار پیش‌فرض به متغیر «[defaultNom]» اختصاص داده می‌شود.
  • خطوط 26–29: همین امر در مورد پارامتر با نام «defaultAge» نیز صدق می‌کند.

متد doPost به متد doGet ارجاع می‌دهد. این بدان معناست که کلاینت می‌تواند پارامترهای خود را با استفاده از POST یا GET ارسال کند.

روش doGet:

  • خط ۳۲: این متد دو پارامتر دریافت می‌کند، `request` و `response`. `request` یک شیء است که نمایانگر کل درخواست کلاینت است. نوع آن `HttpServletRequest` است که یک رابط (interface) می‌باشد. `response` از نوع `HttpServletResponse` است که آن نیز یک رابط (interface) می‌باشد. از شیء `response` برای ارسال پاسخ به کلاینت استفاده می‌شود.
  • `request.getParameter("param")` برای بازیابی مقدار پارامتر با نام «param» از درخواست کلاینت استفاده می‌شود. در خط ۳۶، مقدار پارامتر «txtNom» را بازیابی می‌کنیم؛ در خط ۴۰، مقدار پارامتر «txtAge» را. اگر این پارامترها در درخواست وجود نداشته باشند، مقدار null به‌عنوان مقدار پارامتر بازگردانده می‌شود.
  • خطوط ۳۷–۳۹: اگر پارامتر «txtNom» در پرس‌وجو درج نشود، متغیر «name» با نام پیش‌فرض «defaultNom» که در متد init مقداردهی اولیه شده بود، مقداردهی می‌شود. همین موضوع برای خطوط ۴۱–۴۳ در مورد سن نیز صدق می‌کند.
  • خط ۴۵: response.setContentType(String) برای تعیین مقدار هدر Content-Type HTTP استفاده می‌شود. این هدر به کلاینت اطلاع می‌دهد که ماهیت سندی را که قرار است دریافت کند چیست. نوع 'text/html' نشان‌دهنده یک سند HTML است.
  • خط ۴۶: response.getWriter() برای به‌دست‌آوردن یک جریان نوشتن به سمت کلاینت استفاده می‌شود
  • خطوط ۴۷–۷۸: سند HTML که باید به کلاینت ارسال شود، در استریم خروجی حاصل در خط ۴۶ نوشته می‌شود.

کامپایل این سرولت یک فایل .class در پوشه [build/classes] پروژه [personne] تولید می‌کند:

Image

از خوانندگان دعوت می‌شود تا به راهنمای جاوا در مورد سرولت‌ها مراجعه کنند. می‌توان از 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] است. بنابراین تام‌کت این کلاس را برای رسیدگی به درخواست مشتری واگذار خواهد کرد. اگر این کلاس قبلاً بارگذاری نشده باشد، بارگذاری خواهد شد. سپس برای درخواست‌های آینده در حافظه باقی می‌ماند.

نتیجه زیر با استفاده از مرورگر داخلی اکلیپس به دست آمده است:

Image

ما مقادیر پیش‌فرض برای نام و سن را، همانطور که در فایل [web.xml] مشخص شده است، دریافت می‌کنیم. اکنون بیایید URL و [http://localhost:8080/personne/formulaire?txtNom=tintin&txtAge=30] را درخواست کنیم:

Image

این بار، ما پارامترهای ارسال‌شده در درخواست را دریافت می‌کنیم. به خوانندگان توصیه می‌شود در صورتی که این دو نتیجه را درک نمی‌کنند، کد سرولت [ServletFormulaire] را بررسی کنند.

3.6.6. بارگذاری مجدد خودکار زمینهٔ برنامهٔ وب

بیایید Tomcat را راه‌اندازی کنیم:

Image

سپس بیایید کد servlet را به شرح زیر تغییر دهیم:

     //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;
        }
...
  • خط ۸ اصلاح شده است

بیایید کلاس جدید را ذخیره کنیم. ذخیرهٔ این کار باعث می‌شود Eclipse به‌طور خودکار کلاس [ServletFormulaire] را مجدداً کامپایل کند که Tomcat آن را تشخیص خواهد داد. سپس برای بازتاب تغییرات، زمینهٔ برنامهٔ وب [personne] را مجدداً بارگذاری می‌کند. این موضوع در لاگ‌های نمای [console] مشاهده می‌شود:

Image

بیایید بدون راه‌اندازی مجدد Tomcat، URL [http://localhost:8080/personne/formulaire] را درخواست کنیم:

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>
  • خط ۱۲ اصلاح شده است

پس از انجام این کار، بیایید فایل جدید [web.xml] را ذخیره کنیم. در نمای [console]، هیچ ورودی لاگی که نشان دهد زمینهٔ برنامه دوباره بارگذاری شده است، وجود ندارد. بیایید URL [http://localhost:8080/personne/formulaire] را بدون راه‌اندازی مجدد Tomcat درخواست کنیم:

Image

تغییر اعمال نشده است. بیایید Tomcat را مجدداً راه‌اندازی کنیم [clic droit sur serveur -> Restart -> Start]:

Image

سپس دوباره URL [http://localhost:8080/personne/formulaire] را درخواست کنید:

Image

این بار، تغییری که در [web.xml] اعمال شده قابل مشاهده است.

بنابراین تغییر در [web.xml] باعث بارگذاری مجدد خودکار برنامه‌ای که فایل پیکربندی جدید را در نظر بگیرد، نمی‌شود. برای مجبور کردن برنامه وب به بارگذاری مجدد، می‌توانیم مانند قبل Tomcat را مجدداً راه‌اندازی کنیم، اما این فرآیند نسبتاً کند است. ترجیحاً از ابزار [manager] برای مدیریت برنامه‌های مستقر در Tomcat استفاده کنید. برای این کار، Tomcat باید همان‌طور که در بخش 2.5 نشان داده شده است، در Eclipse پیکربندی شده باشد.

ابتدا، با استفاده از مرورگر داخلی Eclipse، به آدرس [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. ادغام Servlet و JSP صفحه


مطالب مطالعه [ref1]: فصل ۲: ۲.۳.۷


بیایید به دو معماری که بررسی کرده‌ایم بازگردیم:

Image

هیچ‌یک از این دو معماری رضایت‌بخش نیست. هر دو دارای این عیب هستند که دو فناوری را ترکیب می‌کنند: برنامه‌نویسی جاوا که منطق برنامهٔ وب را مدیریت می‌کند، و کدنویسی HTML که ارائهٔ اطلاعات در مرورگر را بر عهده دارد.

  • راه حل [1]، مبتنی بر صفحه JSP، دارای این عیب است که کد HTML و کد جاوا را در یک صفحه واحد با هم مخلوط می‌کند. ما این مشکل را در مثال بررسی‌شده ندیدیم، که یک مثال پایه بود. با این حال، اگر [formulaire.jsp] نیاز داشت پارامترهای [txtNom, txtAge] را در درخواست کلاینت اعتبارسنجی کند، مجبور می‌شدیم کد جاوا را در صفحه قرار دهیم. این وضعیت به سرعت غیرقابل مدیریت می‌شود.
  • راه حل مبتنی بر سرولت [2] نیز همین مشکل را دارد. اگرچه این کلاس تنها حاوی کد جاوا است، اما باید یک سند HTML تولید کند. باز هم، مگر اینکه سند HTML بسیار ساده باشد، تولید آن پیچیده شده و عملاً نگهداری آن غیرممکن می‌شود.

ما با اتخاذ معماری زیر، از ترکیب فناوری‌های جاوا و 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] را انتخاب کنید -> کلیک راست -> جای‌گذاری -> نام را به [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;

     // init
    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 است تغییر کرده است (خطوط ۴۴–۴۶):

  • خط ۴۶: تولید پاسخ توسط صفحه JSP formulaire2.jsp انجام می‌شود. این صفحه که هنوز بررسی نشده است، مسئول نمایش پارامترهای استخراج‌شده از درخواست مشتری خواهد بود: یک نام (خطوط ۳۵–۳۸) و یک سن (خطوط ۳۹–۴۲).
  • این دو مقدار در ویژگی‌های درخواست [request] قرار می‌گیرند که با کلیدها مرتبط هستند. ویژگی‌های یک درخواست به‌صورت یک فرهنگ لغت مدیریت می‌شوند.
  • خط ۴۴: نام در پرس‌وجوی مرتبط با کلید «name» قرار می‌گیرد
  • خط ۴۵: سن در پرس‌وجو قرار می‌گیرد، مرتبط با کلید «age»
  • خط ۴۶: نمایش صفحه 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>

تنها خطوط ۴ تا ۸ نسبت به [formulaire.jsp] تغییر کرده‌اند:

  • خط ۶: مقدار ویژگی با نام «name» را از درخواست [request] بازیابی می‌کند، ویژگی‌ای که توسط servlet [ServletFormulaire2] ایجاد شده است.
  • خط ۷: همین کار را برای ویژگی «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
  • خطوط ۴۲–۴۶: یک بخش <servlet-mapping> برای مرتبط کردن آن با URL /formulaire2

در صورت لزوم سرور Tomcat را راه‌اندازی یا مجدداً راه‌اندازی کنید. ما در حال درخواست URL هستیم

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

Image

ما به همان نتیجه قبلی می‌رسیم، اما ساختار برنامه ما اکنون واضح‌تر است: یک سروِلِت که منطق برنامه را در خود جای داده و وظیفه ارسال پاسخ به کلاینت را به صفحه‌ای به نام JSP واگذار می‌کند. از این پس همیشه به همین روش پیش خواهیم رفت.