إعداد مشروع Java للويب
إعداد مشروع Java للويب
قبل أن تكتب servlet واحدة عليك أن تفهم التخطيط المعياري على القرص الذي يتوقعه كل حاوي Jakarta EE، وكيف تحزم تطبيقك في ملف WAR، وكيف تشغّل ذلك الملف داخل Apache Tomcat. هذا الدرس عملي بالكامل: في نهايته ستمتلك هيكل مشروع يمكنك إعادة استخدامه مع كل servlet ستكتبها في هذا البرنامج التعليمي.
التخطيط المعياري لدليل تطبيق الويب
يتبع تطبيق ويب Jakarta EE عقدًا دقيقًا للأدلة على القرص معرَّفًا بموجب مواصفة Servlet. كل حاوٍ متوافق — Tomcat أو Jetty أو WildFly — يحترم نفس التخطيط:
القاعدة الأهم التي يجب حفظها: كل شيء تحت WEB-INF/ غير مرئي للمتصفح. طلب للمسار /WEB-INF/web.xml يُعيد الحاوي استجابة 404 وليس الملف نفسه. هكذا تُحفظ JSPs التي يجب ألا تُطلب مباشرةً، والإعدادات الحساسة، والفئات المُصرَّفة. أما كل ما يُوضع خارج WEB-INF/ — HTML والصور وCSS — فهو متاح للعموم.
web.xml. استخدم متغيرات البيئة أو مدير الأسرار لبيانات الاعتماد، تمامًا كما تفعل في أي تطبيق آخر على جانب الخادم.
واصف النشر: web.xml
ملف WEB-INF/web.xml هو واصف النشر. إنه ملف XML يخبر الحاوي بمحتوى تطبيقك: أي servlets موجودة، وأي أنماط URL تُعيَّن عليها، ومهلة الجلسة، وملفات الترحيب، وصفحات الأخطاء، وقيود الأمان. منذ Servlet 3.0، حلّت التعليقات التوضيحية (annotations) محل معظم محتواه في الحالات البسيطة، لكن web.xml لا يزال مهمًا للإعدادات التي لا تستطيع التعليقات التوضيحية التعبير عنها وللبيئات التي تُعطَّل فيها مسح التعليقات.
يبدو الحد الأدنى من web.xml الصالح لـ Jakarta EE 10 (Servlet 6.0) هكذا:
لا تُعلَن أي تعيينات للـ servlet هنا لأن الدرس التالي يقدّم تعليق @WebServlet التوضيحي، وهو الطريقة الحديثة لربط عنوان URL بفئة servlet دون لمس web.xml.
web.xml الفارغ لكن الصالح تجاوز الإعدادات المستندة إلى التعليقات التوضيحية لكل بيئة (مثل مهلة جلسة مختلفة في الإنتاج) دون إعادة الترجمة. كما يُعدّ توثيقًا صريحًا لعقد التطبيق.
إعداد بناء Maven (pom.xml)
نوع التعبئة war في Maven يعرف تخطيط تطبيق الويب وينتج WAR بهيكل صحيح تلقائيًا. إليك حدًّا أدنى من pom.xml يستهدف Jakarta EE 10 / Tomcat 10.1:
نطاق provided على تبعية Servlet API بالغ الأهمية. يعني أن Maven يُصرِّف بمقابل الـ API لكنه لا يحزمها داخل ملف WAR. فـ Tomcat يشحن الـ API مسبقًا؛ وإن حزمتها أنت أيضًا ستتعرض لتعارضات في محمّل الفئات وأخطاء ClassCastException يصعب تشخيصها وقت التشغيل.
jakarta.* وليس javax.*. إن كانت استيراداتك لا تزال تقرأ import javax.servlet.* فأنت تستهدف فضاء أسماء Java EE القديم وكودك لن يُنشر على Tomcat 10 أو أي حاوي Jakarta EE 10. حدث إعادة التسمية مع مواصفة Jakarta EE 9 عام 2020. تحقق دائمًا من إصدار Tomcat مقابل إصدار servlet-api الذي تعتمد عليه.
بناء ملف WAR
ملف WAR (Web Application Archive) ما هو إلا ملف ZIP بامتداد .war يحتوي على التخطيط الدليلي الموصوف أعلاه. لبنائه:
يُصرِّف Maven مصادر Java الخاصة بك وينسخها إلى WEB-INF/classes/، وينسخ ملفات JAR التابعة (تلك التي لم تُعطَ نطاق provided) إلى WEB-INF/lib/، ويشمل كل شيء تحت src/main/webapp/، وينتج target/my-webapp.war. يمكنك التحقق من المحتويات:
المخرجات المتوقعة تشمل إدخالات مثل WEB-INF/web.xml وWEB-INF/classes/com/example/web/HelloServlet.class وأي أصول ثابتة.
النشر على Tomcat
يأتي Tomcat 10.1 مزوَّدًا بدليل webapps/. ضع ملف WAR هناك ويُنشره Tomcat تلقائيًا:
يستخرج Tomcat ملف WAR في دليل مطابق (مثل webapps/my-webapp/) ويصبح التطبيق متاحًا على http://localhost:8080/my-webapp/. مسار السياق (/my-webapp) مشتقّ من اسم ملف WAR. للنشر على المسار الجذري، أعد تسمية ملف WAR إلى ROOT.war.
للتطوير، يُتيح لك مكوّن Maven الإضافي لـ Tomcat النشر الفوري دون نسخ يدوي:
هذا يُشغّل نسخة Tomcat مدمجة، ينشر تطبيقك ويبقيه قيد التشغيل. تحصل على دورة تحرير-تصريف-تحديث سريعة دون لمس تثبيت Tomcat مستقل.
التحقق من السجلات
يكتب Tomcat مخرجات بدء التشغيل والنشر في $CATALINA_HOME/logs/catalina.out. إذا فشل نشر WAR — بسبب فضاء أسماء خاطئ في web.xml، أو تعيين servlet معطوب، أو تعارض في محمّل الفئات — ستجد رسالة الخطأ هنا. قراءة هذا السجل هي الخطوة الأولى متى ما ساء أمر النشر.
الخلاصة
أنت الآن تمتلك نموذجًا ذهنيًا قابلًا لإعادة الاستخدام: المحتوى الثابت يقع تحت جذر webapp؛ كل شيء حساس يقع تحت WEB-INF/؛ يصف web.xml عقد التطبيق؛ نطاق provided للـ Servlet API يتفادى تعارضات محمّل الفئات؛ يُنتج mvn clean package ملف WAR؛ ووضعه في webapps/ ينشره. في الدرس التالي ستكتب أول servlet حقيقية وتُعيّنها على عنوان URL.