1. المفاهيم الأساسية
يتم تنفيذ المستمع في Javaweb من خلال نمط تصميم المراقب. فيما يتعلق بوضع المراقب ، لن أعطي الكثير من المقدمة هنا ، لذلك سأتحدث تقريبًا عن ما يعنيه.
يسمى وضع المراقب أيضًا وضع الاشتراك للنشر أو وضع المستمع. هناك حرفين في هذا الوضع: المراقب والمراقب (عادة ما يسمى أيضًا الموضوع). يسجل المراقب حدثًا مهمًا في هذا الموضوع. عند حدوث هذا الحدث ، سيقوم الموضوع بإخطار المراقب من خلال واجهة رد الاتصال.
اسمحوا لي أن أعطيك مثالاً في الحياة: اشترك في الصحف. يمكن لأي عائلة أو فرد الاشتراك في الصحف مع الصحيفة. هنا الصحيفة هي "الموضوع" والأسرة هي "المراقب". على سبيل المثال ، إذا كانت الأسرة بحاجة إلى الاشتراك في الصحيفة صباح الغد ، فهذا "حدث". في صباح اليوم التالي ، تم إنتاج الصحيفة ، وكان هذا "الحدث". عندما يحدث الحادث ، ترسل الصحيفة الصحيفة إلى صندوق البريد المنزلي ، وهو "واجهة رد الاتصال".
بالنسبة للمستمعين في Javaweb ، تحدد مواصفات Servlet بعض أعمدة فئات واجهة المستمع ، وتعرض الأحداث للتطبيق من خلال فئات الواجهة. إذا أراد تطبيق ما الاستماع إلى الأحداث ذات الاهتمام ، فلا يتعين عليه تسجيل الحدث المقابل مباشرة. بدلاً من ذلك ، تكتب مستمعها الخاص لتنفيذ فئة الواجهة المقابلة ويسجل مستمعها الخاص إلى حاوية Servlet. عندما يحدث حدث يهتم به البرنامج ، ستقوم حاوية Servlet بإخطار المستمع وإعادة الاتصال بالطرق في المستمع. المستمع المخصص هنا هو المراقب ، وحاوية Servlet هي السمة.
2. تحليل العينة
كما ذكر أعلاه ، تعرض حاوية Servlet الأحداث للتطبيق من خلال فئة واجهة المستمع. لذلك نحن لسنا الكثير حول تسجيل الأحداث ، بل تسجيل المستمعين. خطوات البرمجة المقابلة هي: 1. اكتب المستمع الخاص بك وتنفيذ واجهة مستمع محددة. 2. سجل المستمع الخاص بك في web.xml. فيما يلي مثال على أبسط واجهة مستمع ServletContextRistener:
1.TestListener.java
تنفذ الفئة العامة testlistener servletContextRistener {public testlistener () {} public void contextInitialized (servletContextevent SCCE) {system.out.println ( {system.out.println ("servletContextRistener.ContextDestroyed") ؛}}2.web.xml
<StaNeer> <Stexer-Class> com.nantang.listener.testListener </leader-class> </stanker>
عند بدء تشغيل الحاوية ، سيتم إخراج "ServletContextListener.ContextInitialized" إلى السجل ، وعندما يتم إغلاق الحاوية ، سيتم إخراج "ServletContextRistener.ContextDestroyed". سيتم تحليل تفسير مفصل في وقت لاحق.
تجدر الإشارة هنا إلى أنه إذا أظهرت المثال أعلاه في IDE (Eclipse ، STS ، وما إلى ذلك) ، عند بدء تشغيل الخادم ، يمكنك رؤية "ServletContextListener.ContextInitialized" في وحدة التحكم ، وعند إغلاق الخادم ، لا يمكنك رؤية "servletcontextener.contextRoyed". ليس هذا هو أن طريقة السياق المعدلة لا يتم تنفيذها ، لكن IDE لا تنفذها تمامًا. للتحقق من أن ContextDestroyed تسمى بالفعل ، يمكنك كتابة قطعة من الكود في ContextDestroyed لإخراج محتويات الملف بدلاً من إخراجها إلى وحدة التحكم.
3. تحليل رمز المصدر
الآن دعنا نحلل الأحداث التي تحددها مواصفات Servlet بالنسبة لنا. بتعبير أدق ، والتي يتم تعريف واجهات الاستماع. تستند المقدمات التالية إلى مواصفات Servlet 3.0.
يوفر لنا Servlet3.0 8 واجهات مستمع ، والتي يمكن تقسيمها إلى ثلاث فئات وفقًا لنطاقها:
1. واجهات الاستماع المتعلقة بالسياق ، بما في ذلك: ServletContextListener و ServletContextAttArbultEntener.
2. واجهات الاستماع المتعلقة بالجلسة HTTP ، بما في ذلك: httpsessionlistener و httpsessionactivationlistener و httpsessionattributelistener و httpsessionBindingListener.
3. واجهة الاستماع المتعلقة بطلب Servlet ، بما في ذلك: ServleTRequestListener و ServleTRequestAtattributeListener.
في الواقع ، من تسمية الواجهة ، يجب أن تكون قادرًا على تخمين وظائفها الأساسية. دعنا نشرح ذلك حسب الفئة أدناه.
1. واجهة الاستماع المرتبطة بالسياق
عند تقديم Servlets من قبل ، أوضحنا أن تطبيق الويب يتوافق مع سياق Servlet. لذلك ، فإن مجموعة حياة الأحداث التي تم الاستماع إليها بواسطة ServletContextRistener و ServletContextAttRiptElistener تعمل عبر تطبيق الويب بأكمله. فيما يلي علاقة التسلسل الهرمي الرسم البياني بين هاتين الواجهتين.
1.1 EventListener
EventListener هي واجهة علامة ، ويجب على جميع مستمعي الأحداث أن يرثوا هذه الواجهة. هذه هي مواصفات servlet ، وليس هناك تفسير.
1.2 EventObject
على غرار EventListener ، فإن EventObject هو فئة على مستوى الحدث ، ويجب أن ترث جميع فئات الأحداث المحددة EventObject.
تنفذ eventoBject من الفئة العامة java.io.serializable {مصدر كائن عابر محمي ؛ eventoBject العام (مصدر الكائن) {if (source == null) رمي alfulalargumentexception جديد ("مصدر null") ؛ هذا. "]" ؛}}هذا الفصل بسيط للغاية ، وجوهره هو مجرد شيء واحد: المصدر. من خلال اسم الفصل EventObject ومصدر اسم الخاصية ، يمكنك أن ترى أن هذه الفئة تقوم بشيء واحد ، مع عقد "كائن مصدر الحدث".
1.3 ServletContextevent
يمتد ServletContexTevent من الفئة العامة java.util.eventObject {public suggletcontextevent (servletcontext source) {super (source) ؛حدث سياق Servlet ، فئة الحدث هذه هي ميراث بسيط لـ EventObject. يتم توفير مثيل ServletContext كمصدر للحدث في المنشئ. نظرًا لأن مصدر الحدث هو سياق servlet ، يتم توفير getServletContext للحصول على مثيل ServletContext.
عندما نوضح فصول الأحداث الأخرى في المستقبل ، فهي جميعها نفس القالب. يوفر كل فئة من فئة الأحداث طريقة البناء المقابلة ، وتمر في كائن مصدر الحدث المقابل ، ويوفر طرقًا إضافية للحصول على مصدر الحدث. لذلك ، EventObject هو الفئة الأساسية لمصدر الحدث. إن جوهر جميع الفئات الفرعية للحدث يقوم بشيء واحد ، وتحديد كائن مصدر الحدث المحدد.
لذا فإن المكان الذي سنشرح فيه الحادث لاحقًا.
1.4 ServletContextListener
الواجهة العامة servletContextListener يمتد EventListener {public void contextinitialized (servletContextevent SCE) ؛ public void contextDestroyed (servletContextevent SCE) ؛}تتوافق واجهة مستمع سياق Servlet مع حدثين: حدث تهيئة سياق Servlet وحدث إغلاق سياق Servlet.
عند تهيئة تطبيق الويب ، ستقوم حاوية Servlet ببناء مثيل ServletContexteven وإعادة الاتصال إلى طريقة السياق.
عندما يكون سياق Servlet على وشك الإغلاق ، عادةً قبل إغلاق الخادم ، ستقوم حاوية Servlet ببناء مثيل ServletContexteven ويعاود الاتصال بأسلوب ContextDestroyed. تجدر الإشارة هنا إلى أن تنفيذ طريقة ContextDestroyed سيتم تنفيذها بعد أن تكمل جميع servlets والمرشحات طريقة التدمير.
لذلك إذا أردنا القيام بشيء ما عند بدء تشغيل التطبيق أو يغلق ، فسوف نكتب المستمع الخاص بنا لتنفيذ الواجهة.
جميع مستمعي الأحداث هم أيضا نفس النموذج. يتم تعريف طريقة واجهة رد اتصال الحدث المقابلة وفقًا لمواصفات Servlet. معلمة إدخال الطريقة هي مثيل مصدر الحدث المقابل. لذلك سوف نمر أيضًا في المكان الذي سنشرح فيه الشاشة لاحقًا.
1.5 ServletContextTribteevent
ServletContextAttRibteevent Public Class يمتد ServletContexTevent {اسم السلسلة الخاصة ؛ قيمة الكائنات الخاصة ؛ public servletContextTributEvent (servletContext source ، اسم السلسلة ، قيمة الكائن) {super (source) ؛ this.name = name ؛ this.value = value ؛ }}يمثل ServletContextTatribteevent حدثًا يتعلق بسمة سياق Servlet. بشكل عام ، سيتم تشغيل الحدث عندما تتغير السمة. يرث هذا الفئة ServletContexteven ، ومصدر الحدث هو أيضًا مثيل ServletContext. يتم توفير طرق إضافية للحصول على أسماء السمات وقيم السمات.
1.6 ServletContextTerBirtInderener
الواجهة العامة servletcontextAttRibtListener تمتد eventListener {public void attributeadded (servletContextAttRibteevent scab) ؛ public void attributeReMoved (servletcontextattributeevent scab) ؛ public void attributeplaced (servletContextexteventeventeviteعند إضافة السمات المذكورة أعلاه من servlet أو حذفها أو تعديلها ، تقوم حاوية Servlet بإنشاء كائن حدث ServletContextTatribteevent ، ودعا الأساليب ذات السمات ، و matributeReMoved و AttributeRedpled على التوالي.
ما تحتاج إلى ملاحظته هنا هو الطريقة المنحقة ، والتي تتصل مرة أخرى عند استبدال قيمة السمة. في هذا الوقت ، إذا قمت بالاتصال بـ ServletContextTirofteevent.getValue () ، فإن الإرجاع هو استبدال قيمة السمة السابقة.
2 واجهة الاستماع ذات الصلة جلسة HTTP
2.1 httpsessionevent
الطبقة العامة httpsessionevent يمتد java.util.eventObject {public httpsessionevent (httpsession source) {super (source) ؛الحدث المتعلق بالجلسة HTTP ، والذي سيتم تشغيله عندما تتغير الجلسة. مصدر الحدث هو مثيل HTTPSESSERESS ويوفر طرق اكتساب HTTPSENESS إضافية.
2.2 httpsessionlistener
الواجهة العامة httpsessionListener تمتد eventListener {public void sessioncreed (httpsessionevent se) ؛ public void sessiondestroyed (httpsessionevent se) ؛}عند إنشاء الجلسة وتدميرها ، تقوم حاوية Servlet بإنشاء كائن حدث HTTPSANSEEVENT وتدعو الأساليب التي تم إنشاؤها و sessiondestroyed.
2.3 httpsessionActivationListener
الواجهة العامة httpsessionActivationListerener يمتد eventListener {public void sessionWillPassive (httpsessionevent se) ؛ public void sessionDidActivate (httpsessionevent se) ؛}عندما تكون الجلسة على وشك أن يتم تنشيطها أو تنشيطها ، تقوم حاوية Servlet بإنشاء كائن حدث HTTPSASENTEVENT ، وجلسة رد الاتصال و SATEDIDACTENCED.
تم شرح التخميل والتنشيط هنا: يشير التخميل إلى أن ذاكرة الخادم غير كافية أو أن مهلة نشاط الجلسة قد وصلت ، والجلسة غير النشطة مؤخرًا متسلسل للقرص. يعني التنشيط أنه يتم الوصول إلى جلسة سلبية مرة أخرى ، مع استحضار الجلسة من القرص إلى الذاكرة.
يمكن أن نرى هنا أنه من أجل تجزئة وتفعيل ، يجب أن يتم تسلسل الجلسة وتسللها أولاً. في الوقت نفسه ، أثناء عملية البرمجة ، نحاول استخدام كائنات بسيطة مثل String و Integer قدر الإمكان ، ونحاول عدم استخدام مجموعات مثل List و Map.
2.4 httpsessionbindingevent
الطبقة العامة httpsessionbindingevent يمتد httpsessionevent {اسم السلسلة الخاصة ؛ قيمة الكائن الخاصة ؛ public httpsessionbindingevent (جلسة httpsession ، اسم السلسلة) {super (جلسة) ؛ this.name = name ؛} httpsessionbindingevent العامة (جلسة httpsession ، اسم السلسلة ، قيمة الكائن) value ؛} public httpsession getSession () {return super.getSession () ؛} السلسلة العامة getName () {return name ؛} الكائن العام getValue () {return this.value ؛ }}يتم تشغيل الحدث المتعلق بسمة جلسة HTTP عندما تتغير سمة الجلسة. مصدر الحدث هو مثيل HTTPSENESS ويوفر طرقًا إضافية للحصول على HTTPSASTINT ، واسم السمة ، وقيمة السمة.
2.5 httpsessionattributelistener
الواجهة العامة httpsessionattributeListener تمتد eventlistener {public void attributeadded (httpsessionBindingevent se) ؛ public void attributeReMoved (httpsessionbindingevent se) ؛ public void attributeplated (httpsessionbindingevent se) ؛}عند إضافة سمة الجلسة أو حذفها أو تعديلها ، تقوم حاوية Servlet بإنشاء كائن حدث HTTPSENESSBINDINGEVENT وتدعو الأساليب المنقوشة ، المنسوجة ، والمقاومة على التوالي على التوالي.
ما تحتاج إلى ملاحظته هنا هو الطريقة المنحقة ، والتي تتصل مرة أخرى عند استبدال قيمة السمة. في هذا الوقت ، إذا قمت بالاتصال بـ ServletContextTirofteevent.getValue () ، فإن الإرجاع هو استبدال قيمة السمة السابقة.
عندما يتم استدعاء طريقة إبطال الجلسة أو فشل الجلسة ، سيتم أيضًا استدعاء طريقة AttributeReMoved مرة أخرى.
2.6 httpsessionBindingListener
الواجهة العامة httpsessionBindingListener تمتد EventListener {public void valueBound (حدث httpsessionbindingevent) ؛ public void valueunbound (حدث httpsessionBindingevent) ؛}يستمع هذا المستمع أيضًا للتغييرات في سمة الجلسة. عند إضافة سمة الجلسة وحذفها ، يكون ذلك ، عندما تكون قيمة السمة ملزمة وقيمة السمة غير ملزمة ، تقوم حاوية servlet بإنشاء كائن حدث HTTPSENESSBINDINGEVENT وتدعو الأساليب المتجهة إلى ValueBound و ValueNbound على التوالي.
لا يبدو الأمر مختلفًا عن httpsessionattributelistener ، ولكن ليس الأمر كذلك. أحد الاختلافات الأساسية بين الاثنين هو حالة الحدث الذي يؤدي إلى.
عندما يكون هناك أي تغيير في خاصية الجلسة ، ستقوم حاوية Servlet بإخطار httpsessionattributelistener. ولكن بالنسبة إلى HTTPSENESSBINDINGLISTERER ، فإن حاوية servlet لن تخطر إلا إذا كانت قيمة الخاصية المرتبطة أو غير المستمع بمثابة مثيل للمستمع. على سبيل المثال:
تنفذ قائمة TestListener من الفئة العامة httpsessionBindingListener {OverRidepublic void valueBound (httpsessionbindingevent event) {system.out.println ( {system.out.println ("httpsessionBindingListener.valueunbound") ؛}}نقوم بتخصيص قائمة TestListener المستمع لتنفيذ httpsessionBindingListener. دعنا نضع سمة الجلسة التالية في الكود:
httpsession session = request.getSession () ؛ testlistener testlistener = new testlistener () ؛ session.setAttribute ("المستمع" ، testlistener) ؛ Session.RemoVeatTribute ("المستمع") ؛هنا قيمة السمة للجلسة هي مثيل TestListener للمستمع. لذلك عند تنفيذ هذا الرمز ، ستقوم حاوية Servlet بإخطار قائمة Testlistener وتعيد الاتصال بطرق ValueBound و ValueNbound.
تجدر الإشارة هنا إلى أنه عندما يتم استدعاء الطريقة الإلغاء للجلسة أو فشل الجلسة ، سيتم أيضًا استدعاء طريقة ValueNbound مرة أخرى.
3 واجهة الاستماع المتعلقة بطلب Servlet
3.1 servletrequestevent
يمتد ServleTRequestevent من الفئة العامة java.util.eventObject {private servletrequest (servletcontext) super.getsource () ؛}}سيتم تشغيل الحدث المتعلق بطلب Servlet عندما يتغير الطلب. مصدر الحدث هو مثيل ServletContext ويوفر جلبًا إضافيًا لطرق ServletContext و ServleTRequest.
3.2 ServletRequestListener
الواجهة العامة servletRequestListener يمتد EventListener {public void requestDestroyed (servletrequestevent sre) ؛ public void requestInitialized (servletrequestevent sre) ؛}عند تهيئة الطلب أو تدميره ، يطلب العميل إدخال تطبيق الويب (أدخل servlet أو المرشح الأول) أو يقوم تطبيق الويب بإرجاع استجابة للعميل (الخروج من servlet أو المرشح الأول). تقوم حاوية Servlet بإنشاء مثيل ServleTRequestevent ، وتدعو أساليب الطلب والطلب.
3.3 ServletRequestAttributevent
ServleTRequestAtTributEvent Public ServleTRequestEvent {اسم السلسلة الخاصة ؛ قيمة الكائنات الخاصة ؛ public secretRequestAtTributEvent (servletcontext sc ، servletrequest request ، اسم السلسلة ، قيمة الكائن) {super (sc ، request) ؛ name = name ؛ هذا. }}يطلب الحدث المتعلق بـ Servlet السمة ، والتي سيتم تشغيلها عندما تتغير سمة الطلب. مصدر الحدث هو مثيل ServletContext ويوفر طرقًا إضافية للحصول على أسماء السمات وقيم السمات.
3.4 ServletRequestAtTributElistener
الواجهة العامة servletrequestattributeListener تمتد eventListener {public void attributeadded (servletrequestattributevent srae) ؛ public void atritfiteremoved (servletrequestattributeevent srae) ؛ public void attributeplaced (servletrequestattirebitevent srae) ؛}عند إضافة السمات المطلوبة أو حذفها أو تعديلها ، تقوم حاوية Servlet بإنشاء كائن حدث ServleTRequestAtatTributevent ، واستدعاء الأساليب المنقوشة ، المنسوبة ، والمعارلة على التوالي.
ما تحتاج إلى ملاحظته هنا هو الطريقة المنحقة ، والتي تتصل مرة أخرى عند استبدال قيمة السمة. في هذا الوقت ، إذا قمت بالاتصال بـ ServleTRequestAtTributeVent.getValue () ، فإن الإرجاع هو استبدال قيمة السمة السابقة.
4. ملخص
في هذه المرحلة ، انتهى المستمع من التحدث. يمكننا أن نجد أن المستمع و Servlet و Filter لهما شيء واحد مشترك ، وكلاهما من المقرر أن يكون كلاهما بواسطة الحاويات. نحتاج فقط إلى كتابة المستمع الخاص بنا لتنفيذ واجهة المستمع التي نهتم بها والتسجيل. بقية الوظيفة هي كتابة منطق الأعمال في مستمعنا.
يتم صياغة المستمع الذي تم تقديمه في منشور المدونة هذا بواسطة مواصفات Servlet 3.0. 3.1 أضاف بعض واجهات مستمع الأحداث ، والمبادئ متشابهة ، يمكن للقراء فهمها بأنفسهم.