كل مطور يستخدم servlet اليوم يعرف JSP، وهي تقنية ويب اخترعتها شركة Sun Microsystems وبذلت الكثير من الجهد للترويج لتقنية servlet والبناء عليها. يقوم JSP بفصل كود HTML عن servlet، وبالتالي تسريع تطوير تطبيقات الويب وصيانة الصفحة. في الواقع، فإن وثيقة "نموذج تطوير التطبيقات" الرسمية التي نشرتها شركة Sun تذهب إلى أبعد من ذلك: "يجب اعتبار تقنية JSP معيارًا، ويمكن اعتبار servlets مكملة في معظم الحالات." الاستماع إلى نسخة الآراء).
الغرض من هذه المقالة هو سماع تقييم لمدى معقولية هذا البيان - من خلال مقارنة JSP بتقنية أخرى قائمة على servlets: محركات القوالب.
مشاكل في استخدام السيرفلتس مباشرة
في البداية، تم اختراع السيرفلتس ورأى العالم كله تفوقها. يمكن تنفيذ صفحات الويب الديناميكية المستندة إلى servlets بسرعة، ويمكن نقلها بسهولة بين خوادم متعددة، ويمكن دمجها بشكل مثالي مع قاعدة البيانات الخلفية. يتم قبول Servlets على نطاق واسع باعتبارها النظام الأساسي المفضل لخوادم الويب.
ومع ذلك، فإن كود html الذي يتم تنفيذه عادةً بطريقة بسيطة يتطلب الآن من المبرمج استدعاء out.println() لكل سطر من HTML، الأمر الذي أصبح مشكلة خطيرة في تطبيقات servlet الفعلية. يجب تنفيذ محتوى HTML من خلال التعليمات البرمجية، وهي مهمة شاقة وتستغرق وقتًا طويلاً بالنسبة لصفحات HTML الكبيرة. بالإضافة إلى ذلك، كان على الأشخاص المسؤولين عن محتوى الويب تعيين مطورين لإجراء كافة التحديثات. ولهذا السبب يبحث الناس عن حل أفضل.
وصول JSP!
ظهر JSP 0.90. في هذه التقنية، تقوم بتضمين كود Java في ملف HTML وسيقوم الخادم تلقائيًا بإنشاء servlet للصفحة. يعتبر JSP طريقة سهلة لكتابة servlets. يمكن الحصول على كل HTML مباشرة دون الحاجة إلى استدعاء out.println()، ويمكن للشخص المسؤول عن محتوى الصفحة تعديل HTML مباشرة دون المخاطرة بكسر كود Java.
ومع ذلك، فإن وجود فناني ومطوري الصفحات الذين يعملون على نفس الملف لم يكن أمرًا مثاليًا، وقد ثبت أن تضمين Java في HTML أمر محرج مثل تضمين HTML في Java. لا يزال من الصعب قراءة الفوضى في التعليمات البرمجية.
ونتيجة لذلك، أصبح الناس ناضجين في استخدام jsp واستخدموا JavaBeans أكثر. تحتوي الفاصوليا على رمز منطق الأعمال الذي يتطلبه jsp. يمكن إخراج معظم التعليمات البرمجية في JSP ووضعها في الحبة، مع ترك كمية صغيرة جدًا من العلامات لاستدعاء الحبة.
في الآونة الأخيرة، بدأ الناس يعتقدون أن صفحات JSP بهذه الطريقة تشبه المشاهدات حقًا. تصبح مكونًا يستخدم لعرض نتائج طلبات العميل. لذلك سوف يفكر الناس، لماذا لا يتم إرسال طلب مباشرة إلى العرض؟ ماذا يحدث إذا كان العرض المستهدف غير مناسب للطلب؟ بعد كل شيء، العديد من الطلبات لديها إمكانيات متعددة للحصول على عرض النتيجة. على سبيل المثال، قد ينتج عن نفس الطلب صفحة ناجحة، أو تقرير خطأ في استثناء قاعدة البيانات، أو تقرير خطأ للمعلمات المفقودة. قد ينتج عن نفس الطلب صفحة باللغة الإنجليزية أو صفحة باللغة الإسبانية، اعتمادًا على لغة العميل. لماذا يجب على العميل إرسال الطلب مباشرة إلى العرض؟ لماذا لا يجب على العميل إرسال الطلب إلى بعض مكونات الخادم العامة والسماح للخادم بتحديد ما يعرضه عرض JSP
؟ تصميم النموذج 2 "، هذا نموذج يعتمد على عرض النموذج ووحدة التحكم المحددة في JSP 0.92. في هذا التصميم، يتم إرسال الطلبات إلى وحدة تحكم servlet، التي تنفذ منطق الأعمال وتقوم بإنشاء "نموذج" بيانات مماثل للعرض. يتم بعد ذلك إرسال هذه البيانات داخليًا إلى "عرض" JSP للعرض، مما يجعل صفحة JSP تبدو وكأنها JavaBean عادية مضمنة. يمكن تحديد صفحة JSP المناسبة للعرض بناءً على المنطق الداخلي لـ servlet المسؤول عن التحكم. بهذه الطريقة، يصبح ملف JSP عرض قالب جميل. يعد هذا تطورًا آخر وقد أشاد به المطورون الآخرون حتى يومنا هذا.
أدخل محرك القالب
واستخدم محرك القالب ليحل محل JSP للأغراض العامة. سيصبح التصميم اللاحق أبسط، وسيكون بناء الجملة أكثر بساطة، وستكون رسالة الخطأ أسهل في القراءة وستكون الأدوات أكثر سهولة في الاستخدام. قامت العديد من الشركات بتصنيع مثل هذه المحركات، أشهرها على الأرجح WebMacro ( http://webmacro.org ، من Semiotek)، ومحركها مجاني.
يجب أن يفهم المطورون أن اختيار محرك قالب ليحل محل JSP يوفر مثل هذه المزايا التقنية، والتي تعد أيضًا بعض عيوب jsp:
المشكلة رقم 1: كود Java مقولب للغاية
على الرغم من أنه يعتبر تصميمًا سيئًا، إلا أن JSP لا يزال يحاول إضافة Java رمز إلى صفحة الويب. هذا يشبه إلى حد ما ما فعلته Java من قبل، وهو تعديل مبسط لـ C++، كما قامت محركات القالب بتبسيطه عن طريق إزالة كود المصدر ذي المستوى الأدنى في jsp. تنفذ محركات القوالب تصميمًا أفضل.
السؤال رقم 2: يتطلب كود Java
يلزم كتابة بعض أكواد Java في صفحة JSP. على سبيل المثال، لنفترض أن إحدى الصفحات تحدد السياق الجذري لتطبيق الويب الحالي وتؤدي إلى صفحته الرئيسية.
من الأفضل استخدام كود Java التالي في JSP:
<a href="<%= request.getContextPath() %>/index.html">الصفحة الرئيسية</a>
يمكنك محاولة تجنب كود Java واستخدام علامة <jsp:getProperty> ولكن ذلك سيمنحك ستة سلاسل غير قابلة للقراءة:
<a href="<jsp:getProperty name="request"
property="contextPath"/>/index.html">HomePage</a>
باستخدام محرك القالب، لا يوجد كود Java وبناء جملة قبيح. وإليك كيفية كتابته في WebMacro تحت نفس المتطلبات:
<a href="$ Request.ContextPath ;/index.html">الصفحة الرئيسية</a>
في WebMacro، يتم استخدام contextPath كسمة لمتغير $Request، باستخدام بناء جملة يشبه Perl. وتستخدم محركات القوالب الأخرى أنواع بناء جملة أخرى.
بالنظر إلى مثال آخر، لنفترض أن "العرض" المتقدم يحتاج إلى تعيين ملف تعريف ارتباط لتسجيل تكوين اللون الافتراضي للمستخدم - يبدو من المحتمل أن تكتمل هذه المهمة بواسطة العرض بدلاً من وحدة تحكم servlet. يجب أن يكون هناك كود Java في JSP:
<% Cookie c = new Cookie("colorscheme", "blue"); Response.addCookie(c);
لا يوجد كود Java في WebMacro:
#set $Cookie.colorscheme = "الأزرق"
هو الأيون الأخير، إذا كنت تريد استرداد تكوين اللون في ملف تعريف الارتباط الأصلي. بالنسبة لـ JSP، يمكننا التفكير في فئة أداة مقابلة للمساعدة، لأنه سيكون أمرًا سخيفًا وصعبًا القيام بمثل هذه الأشياء ذات المستوى المنخفض مباشرةً باستخدام getCookies(). في JSP:
<% Stringcolorscheme = ServletUtils.getCookie(request, "colorscheme" %>
ليست هناك حاجة لفئات الأدوات في WebMacro، عادةً: $Cookie.colorscheme.Value. بالنسبة لفناني الجرافيك الذين يكتبون JSP، ما هو بناء الجملة الأسهل في التعلم؟
قدم JSP 1.1 علامات مخصصة تسمح للعلامات العشوائية الشبيهة بـ HTML بتنفيذ تعليمات Java البرمجية في الخلفية في صفحات JSP، وسيكون لهذا بعض القيمة، ولكن فقط إذا كانت هناك مكتبة علامات موحدة معروفة على نطاق واسع ومتكاملة الميزات ومتوفرة مجانًا. لا توجد مكتبة علامات كهذه حاليًا.
المشكلة رقم 3: المهام البسيطة لا تزال متعبة
حتى المهام البسيطة، مثل تضمين الرؤوس والتذييلات، لا تزال صعبة للغاية في JSP. لنفترض أن هناك قالب "رأس" و"تذييل" ليتم تضمينهما في جميع الصفحات، ويجب أن يحتوي كل قالب على عنوان الصفحة الحالية في المحتوى.
أفضل طريقة في JSP هي:
<% عنوان السلسلة = "عنوان الصفحة" %>
<%@ تضمين الملف = "/header.jsp" %>
...محتوى صفحتك...
<%@ include file="/footer.jsp" %>
يجب أن يتذكر مصممو الصفحة عدم حذف الفاصلة المنقوطة في السطر الأول وتحديد العنوان كسلسلة. بالإضافة إلى ذلك، يجب أن يكون /header.jsp و/footer.jsp موجودين في الدليل الجذر ويجب أن يكونا ملفين يمكن الوصول إليهما بشكل كامل.
يعد تضمين الرؤوس والتذييلات في WebMacro أمرًا بسيطًا نسبيًا:
#set $title = "The Page Title"
#تحليل "header.wm"
المحتوى الخاص بك هنا
#parse "footer.wm"
لا توجد فواصل منقوطة أو تعريفات عناوين ليتذكرها المصممون، ويمكن وضع ملفات .wm في مسار بحث قابل للتخصيص.
المشكلة رقم 4: الحلقات السميكة جدًا
تعد التكرارات في JSP أمرًا صعبًا. هنا، يتم استخدام JSP لطباعة اسم كل كائن ISP بشكل متكرر.
<%
التعداد e = list.elements();
بينما (e.hasMoreElements()) {
out.print("الاسم التالي هو");
println(((ISP)e.nextElement()).getName());
out.print("<br>");
}
%>
ربما ستكون هناك علامات معرفة من قبل المستخدم للقيام بهذه الحلقات في وقت ما. الشيء نفسه ينطبق على "إذا". قد تبدو صفحات JSP وكأنها كود Java غريب. وفي الوقت نفسه، حلقة webmacro جميلة:
#foreach $isp في $isps {
الاسم التالي هو $isp.Name <br>
}
إذا لزم الأمر، يمكن بسهولة استبدال التوجيه #foreach بتوجيه مخصص #foreach-backwards.
إذا كنت تستخدم jsp، فقد يصبح الأمر على النحو التالي: (إليك علامة <foreach> المحتملة)
<foreach item="isp" list="isps">
الاسم التالي هو <jsp:getProperty name="isp" property="name"/> <br>
</foreach>
سيختار المصمم الخيار الأول بطبيعة الحال.
المشكلة رقم 5: رسائل الخطأ غير المفيدة
غالبًا ما تحتوي برامج JSP على بعض رسائل الخطأ المفاجئة. وذلك لأن الصفحة يتم تحويلها أولاً إلى servlet ثم يتم تجميعها. يمكن لأدوات JSP الجيدة أن تزيد نسبيًا من احتمالية العثور على موقع الخطأ، ولكن حتى أفضل الأدوات لا يمكنها جعل جميع رسائل الخطأ قابلة للقراءة بسهولة. بسبب عملية التحويل، قد يكون من المستحيل على الأداة تحديد بعض الأخطاء.
على سبيل المثال، لنفترض أن صفحة JSP تحتاج إلى إنشاء عنوان مشترك لجميع الصفحات. لا يوجد خطأ في الكود التالي:
<% static String title = "Global title" %>
لكن Tomcat سيقدم رسالة الخطأ التالية:
العمل/%3A8080%2F/JC_0002ejspJC_jsp_1.java:70: البيان متوقع.
عدد صحيح ثابت = 0؛
^
تعتقد هذه المعلومات أنه تم وضع البرنامج النصي أعلاه في طريقة _jspService() ولا يُسمح بوضع المتغيرات الثابتة في الطريقة. يجب أن يكون بناء الجملة <%! من الصعب على مصممي الصفحات قراءة رسائل الخطأ هذه. حتى أفضل المنصات تفشل في هذا الصدد. حتى أن نقل كافة أكواد Java خارج الصفحة لا يحل المشكلة. وأيضا ما الخطأ في التعبير التالي؟
<% عدد %>
القط يعطي:
العمل/8080/_0002ftest_0002ejsptest_jsp_0.java:56: عدد الفصول غير موجود في
نوع الإعلان.
عدد
^
العمل/8080/_0002ftest_0002ejsptest_jsp_0.java:59: إعلان غير صالح.
out.write("rn");
^
بمعنى آخر، إنها مجرد علامة مفقودة. ينبغي أن يكون <%= العد %>.
نظرًا لأنه يمكن إنشاء محرك القالب مباشرةً من ملف القالب دون أي ترجمة دراماتيكية إلى تعليمات برمجية، فمن السهل جدًا تقديم تقرير مناسب عن الأخطاء. على سبيل القياس، عندما تتم كتابة أمر لغة C في سطر الأوامر الخاص بصدفة Unix، فأنت لا تريد أن تقوم الصدفة بإنشاء برنامج C لتشغيل الأمر، ولكنك تحتاج فقط إلى الصدفة لتفسير الأمر وتنفيذه ببساطة. والإبلاغ مباشرة عن أي أخطاء.
المشكلة رقم 6: الحاجة إلى مترجم
JSP يتطلب وجود مترجم في خادم الويب. أصبح هذا مشكلة لأن شركة Sun رفضت التخلي عن مكتبة Tools.jar التي تحتوي على مترجم javac الخاص بها. يمكن أن يتضمن خادم الويب مترجمًا تابعًا لجهة خارجية مثل Jikes من IBM. لكن مثل هذا المترجم لا يعمل بسلاسة على جميع الأنظمة الأساسية (مكتوب بلغة C++) ولا يساعد على إنشاء خادم ويب Java خالص. يحتوي JSP على خيار الترجمة المسبقة الذي يساعد، على الرغم من أنه ليس مثاليًا.
المشكلة رقم 7: إهدار المساحة
JSP يستهلك ذاكرة إضافية ومساحة على القرص الصلب. لكل ملف JSP بحجم 30 كيلو بايت على الخادم، يجب إنشاء ملف فئة مناظر أكبر من 30 كيلو بايت. يضاعف مساحة القرص الصلب بشكل فعال. بالنظر إلى أن ملف JSP يمكنه بسهولة تضمين ملف بيانات كبير من خلال <%@ include> في أي وقت، فإن هذا الاهتمام له أهمية عملية للغاية. في الوقت نفسه، يجب تحميل بيانات ملف الفئة لكل JSP في ذاكرة الخادم، مما يعني أن ذاكرة الخادم يجب أن تحفظ شجرة مستندات JSP بأكملها إلى الأبد. تتمتع بعض أجهزة JVM بالقدرة على نقل بيانات ملف فئة من الذاكرة؛ ومع ذلك، لا يملك المبرمج عادةً أي سيطرة على قواعد إعادة التصريح، وقد لا تكون إعادة التصريح فعالة جدًا للمواقع الكبيرة. بالنسبة لمحركات القوالب، يتم حفظ المساحة لأنه لا يتم إنشاء ملف ثانٍ. توفر محركات القوالب أيضًا للمبرمجين تحكمًا كاملاً في كيفية تخزين القوالب مؤقتًا في الذاكرة.
توجد أيضًا بعض المشكلات في استخدام محرك القالب:
مشكلة القالب رقم 1: لم يتم تعريفها بشكل صارم
ولم يتم تحديد كيفية عمل محرك القالب بشكل صارم. ومع ذلك، بالمقارنة مع JSP، فإن هذا في الواقع ليس مهمًا جدًا، على عكس JSP، ليس لدى محركات القوالب أي متطلبات خاصة لخادم الويب - يمكن لأي خادم يدعم servlets دعم محركات القوالب (بما في ذلك خوادم API 2.0 مثل Apache/JServ، فهي). لا تدعم JSP بشكل كامل)! إذا كانت المنافسة الصحية للحصول على أفضل تصميم لمحرك القالب قد تسببت في ابتكار مبهر، خاصة مع الترويج للمصادر المفتوحة (السماح للأفكار بدفع وترويج بعضها البعض)، فإن WebMacro اليوم سيكون مثل Perl. لم يتم تعريفه بشكل صارم ولكن الترويج للمؤسسات مفتوحة المصدر هو معياره.
مشكلة القالب رقم 2: لم يتم التعرف على
محركات القالب غير معروفة على نطاق واسع. لقد احتلت JSP سوقًا تجاريًا ضخمًا وهي متجذرة بعمق في قلوب الناس. لا يمكن أن يكون استخدام محركات القوالب g سوى تقنية بديلة غير مفهومة.
مشكلة القالب رقم 3: لم يتم نشر
محركات القالب لم يتم تكوينها بشكل كبير بعد. لا يوجد اختبار أداء ومقارنة بين محرك القالب وJSP. من الناحية النظرية، يجب أن يتطابق تطبيق محرك القالب الذي تم نشره جيدًا مع JSP الذي تم نشره جيدًا؛
دور JSP
بالطبع، سيكون لـ JSP بالتأكيد مكانه في المستقبل. يمكن ملاحظة التشابه بين JSP وASP حتى من الأسماء، فهما يختلفان بحرف واحد فقط. لذلك، إذا كان الأشخاص الذين يستخدمون ASP سيتحولون إلى Java، فإن بيئة JSP المتشابهة جدًا ستلعب دورًا كبيرًا في تعزيز ذلك. يجب أن يكون دور الحفاظ على هذه العلاقة المقابلة مع ASP أيضًا أحد الاعتبارات الرئيسية للمصممين الذين يطلقون JSP.
ومع ذلك، النقطة هنا هي أن هناك فرقًا كبيرًا بين ما يفيد العمال الذين ينتقلون إلى بيئة جديدة وما إذا كانت هذه هي أفضل طريقة لاستخدام تلك البيئة بالفعل.
تُظهر JSP بشكل متزايد أنها أصبحت واحدة من أهم تقنيات Java، وتسمح للأشخاص بمغادرة عالم ASP - وبالتالي، ستدعم Sun هذه الحالة التجارية القوية، كما سيقدم مؤيدو التكنولوجيا المرتبطة بـ Java دعمًا أكبر.
ومع ذلك، هذا ليس الحل الأفضل لمنصة جافا. وهذا سيجعل حل Java يبدو وكأنه حل بدون Java.