لم يتم استدعاء CommandButton/CommandLink/Ajax Action/المستمع
-
22-09-2019 - |
سؤال
في بعض الأحيان ، عند استخدام <h:commandLink>
, <h:commandButton>
أو <f:ajax>
, ، ال action
, actionListener
أو listener
الطريقة المرتبطة بالعلامة لا يتم استدعاؤها ببساطة. أو لا يتم تحديث خصائص الفول مع تقديمها UIInput
القيم.
ما هي الأسباب والحلول المحتملة لهذا؟
المحلول
مقدمة
كلما كان UICommand
عنصر (<h:commandXxx>
, <p:commandXxx>
, ، إلخ) فشل في استدعاء طريقة الإجراء المرتبطة بها ، أو UIInput
عنصر (<h:inputXxx>
, <p:inputXxxx>
, ، وما إلى ذلك) فشل في معالجة القيم المقدمة و/أو تحديث قيم النموذج ، ولا ترى أي استثناءات و/أو تحذيرات قابلة للوجود في سجل الخادم ، ليس عند تكوين معالج استثناء AJAX وفقًا لل استثناء معالجة في طلبات JSF Ajax, ، ولا عند تعيين معلمة السياق أدناه في web.xml
,
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
وأنت أيضًا لا ترى أي أخطاء و/أو تحذيرات قابلة للوجود في وحدة تحكم JavaScript في المتصفح (اضغط F12 في Chrome/Firefox23+/IE9+ لفتح مجموعة أدوات مطور الويب ثم افتح وحدة التحكم علامة التبويب) ، ثم اعمل من خلال قائمة الأسباب المحتملة أدناه.
الأسباب المحتملة
UICommand
وUIInput
يجب وضع المكونات داخلUIForm
مكون ، على سبيل المثال<h:form>
(وبالتالي ليس HTML عادي<form>
) ، وإلا لا يمكن إرسال أي شيء إلى الخادم.UICommand
يجب ألا يكون المكونات أيضًاtype="button"
السمة ، وإلا فإنه سيكون زر ميت وهو مفيد فقط لجافا سكريبتonclick
. أنظر أيضا كيفية إرسال قيم إدخال النموذج واستدعاء طريقة في JSF Bean و u003Ch:commandButton>لا يبدأ بعد الظهر.لا يمكنك عش متعددة
UIForm
مكونات في بعضها البعض. هذا غير قانوني في HTML. سلوك المتصفح غير محدد. احترس من تضمين الملفات! يمكنك استخدامUIForm
المكونات بالتوازي ، لكنها لن تعالج بعضها البعض أثناء إرسالها. يجب عليك أيضًا الانتباه إلى "شكل الله" المضاد ؛ تأكد من عدم معالجة/التحقق من صحة جميع المدخلات الأخرى (غير المرئية) في نفس النموذج (مثل وجود مربع حوار مخفي مع المدخلات المطلوبة في نفس النموذج). أنظر أيضا كيف تستعملu003Ch:form> في صفحة JSF؟ شكل واحد؟ أشكال متعددة؟ أشكال متداخلة؟.لا
UIInput
يجب أن يكون خطأ التحقق من صحة القيمة/التحويل. يمكنك استخدام<h:messages>
لإظهار أي رسائل لا تظهرها أي إدخال خاص<h:message>
عناصر. لا تنس تضمينid
من<h:messages>
في ال<f:ajax render>
, ، إن وجدت ، بحيث يتم تحديثها أيضًا على طلبات Ajax. أنظر أيضا H: لا تعرض الرسائل رسائل عند الضغط على P: CommandButton.لو
UICommand
أوUIInput
يتم وضع المكونات داخل مكون تكرار مثل<h:dataTable>
,<ui:repeat>
, ، إلخ ، فأنت بحاجة إلى التأكد من ذلك بالضبطvalue
يتم الحفاظ على المكون المتكرر أثناء مرحلة قيم طلب الطلب لطلب إرسال النموذج. سيقوم JSF بتكراره للعثور على الرابط/الزر الذي تم النقر عليه وقيم الإدخال المقدمة. وضع الفول في نطاق العرض و/أو التأكد من تحميل نموذج البيانات في@PostConstruct
من الفول (وبالتالي ليس في طريقة getter!) يجب إصلاحه. أنظر أيضا كيف ومتى يجب أن أقوم بتحميل النموذج من قاعدة البيانات لـ H: DataTable.لو
UICommand
أوUIInput
يتم تضمين المكونات بواسطة مصدر ديناميكي مثل<ui:include src="#{bean.include}">
, ، ثم تحتاج إلى التأكد من ذلك بالضبط#{bean.include}
يتم الحفاظ على القيمة أثناء عرض وقت إنشاء النموذج. سوف JSF إعادة الاستمرار عليه أثناء بناء شجرة المكون. وضع الفول في نطاق العرض و/أو التأكد من تحميل نموذج البيانات في@PostConstruct
من الفول (وبالتالي ليس في طريقة getter!) يجب إصلاحه. أنظر أيضا كيف تتضمن Ajax-Refresh Dynamic المحتوى عن طريق قائمة التنقل؟ (JSF Spa).ال
rendered
سمة المكون وجميع والديه وtest
سمة أي والد<c:if>
/<c:when>
لا ينبغي التقييم لfalse
أثناء مرحلة طلب طلب الطلب من طلب إرسال النموذج. ستقوم JSF بإعادة فحصها كجزء من الحماية ضد الطلبات المعلبة/المخترقة. تخزين المتغيرات المسؤولة عن الحالة في أ@ViewScoped
الفول أو التأكد من أنك تضع الحالة بشكل صحيح في@PostConstruct
من@RequestScoped
يجب أن يصلحها الفول. الأمر نفسه ينطبق علىdisabled
سمة المكون ، والتي لا ينبغي تقييمهاtrue
أثناء تطبيق مرحلة قيم الطلب. أنظر أيضا لم يتم الاحتجاج بنشاط JSF CommandButton و لا تتم معالجة النموذج في المكون المقدم بشكل مشروط.ال
onclick
سمة منUICommand
مكون وonsubmit
سمة منUIForm
يجب ألا يعود المكونfalse
أو تسبب خطأ جافا سكريبت. يجب أن يكون هناك في حالة<h:commandLink>
أو<f:ajax>
كما لا توجد أخطاء JS مرئية في وحدة التحكم JS في المتصفح. عادةً ما تعطيك رسالة الخطأ الدقيقة بالفعل الإجابة. أنظر أيضا يؤدي إضافة jQuery إلى Primefaces إلى نتائج غير معلنة.إذا كنت تستخدم AJAX عبر JSF 2.x
<f:ajax>
أو على سبيل المثال<p:commandXxx>
, ، تأكد من أن لديك<h:head>
في القالب الرئيسي بدلاً من<head>
. وإلا فإن JSF لن تتمكن من تلقائي تلقائيًا ملفات JavaScript اللازمة التي تحتوي على وظائف AJAX. سيؤدي ذلك إلى خطأ JavaScript مثل "Mojarra غير محدد" أو "Primefaces غير محدد" في وحدة التحكم JS في المتصفح. أنظر أيضا H: لا يتم استدعاء CommandLink ActionListener عند استخدامها مع F: Ajax و UI: كرر.إذا كنت تستخدم Ajax ، وينتهي الأمر بالقيم المقدمة
null
, ، ثم تأكد من أنUIInput
وUICommand
يتم تغطية مكونات الاهتمام من قبل<f:ajax execute>
أو على سبيل المثال<p:commandXxx process>
, ، وإلا فلن يتم تنفيذها/معالجتها. أنظر أيضا قيم النموذج المقدمة لم يتم تحديثها في النموذج عند الإضافةu003Cf:ajax> لu003Ch:commandButton> و فهم عملية/تحديث PrimeFaces و JSF F: سمات تنفيذ/تقديم AJAX.إذا كانت القيم المقدمة لا تزال تنتهي
null
, ، وأنت تستخدم CDI لإدارة الفاصوليا ، ثم تأكد من استيراد التعليق التوضيحي للنطاق من الحزمة الصحيحة ، وإلا فإن CDI سوف تتخلف عن@Dependent
الذي يعيد بفعالية الفول على كل تقييم واحد للتعبير EL. أنظر أيضا sessionscoped Bean يفقد نطاقه ويتم إعادة إنشاءه طوال الوقت ، تصبح الحقول خالية و ما هو نطاق الفول المدار الافتراضي في تطبيق JSF 2؟إذا كان أحد الوالدين
<h:form>
مع الUICommand
يتم تقديم/تحديث الزر قبل طلب AJAX قادمًا من نموذج آخر في نفس الصفحة ، فإن الإجراء الأول سيفشل دائمًا في JSF 2.2 أو أكبر. الإجراءات الثانية واللاحقة ستعمل. هذا ناتج عن وجود خطأ في عرض الحالة التي يتم الإبلاغ عنها على أنها JSF SPEC Issue 790 ومثبت حاليًا في JSF 2.3. بالنسبة لإصدارات JSF القديمة ، تحتاج إلى تحديد معرف<h:form>
في الrender
التابع<f:ajax>
. أنظر أيضا H: CommandButton/H: لا يعمل CommandLink على النقر أولاً ، يعمل فقط على النقر الثاني.إذا
<h:form>
لديهاenctype="multipart/form-data"
تعيين لدعم تحميل الملفات ، ثم تحتاج إلى التأكد من أنك تستخدم على الأقل JSF 2.2 ، أو أن مرشح Servlet المسؤول عن تحليل طلبات multipart/form بشكل صحيح ، وإلاFacesServlet
سوف ينتهي الأمر بالحصول على أي معلمات طلب على الإطلاق ، وبالتالي لا تكون قادرًا على تطبيق قيم الطلب. تعتمد كيفية تكوين مثل هذا المرشح على مكون تحميل الملف المستخدم. من أجل توماهوك<t:inputFileUpload>
, ، التحقق من هذا الجواب وللأمر<p:fileUpload>
, ، التحقق من هذا الجواب. أو ، إذا كنت في الواقع لا تقوم بتحميل ملف على الإطلاق ، فقم بإزالة السمة تمامًا.تأكد من أن
ActionEvent
حجةactionListener
هوjavax.faces.event.ActionEvent
وبالتالي لاjava.awt.event.ActionEvent
, ، وهو ما تشير إليه معظم IDEs كخيار الإكمال التلقائي الأول. عدم وجود حجة خطأ أيضًا إذا كنت تستخدمactionListener="#{bean.method}"
. إذا كنت لا تريد وسيطة في طريقتك ، فاستخدمactionListener="#{bean.method()}"
. أو ربما تريد استخدامها بالفعلaction
بدلاً منactionListener
. أنظر أيضا الاختلافات بين العمل و ActionListener.تأكد من أن لا
PhaseListener
أو أيEventListener
في سلسلة استجابة الطلب ، غيرت دورة حياة JSF لتخطي مرحلة إجراء الاستدعاء على سبيل المثال الاتصالFacesContext#renderResponse()
أوFacesContext#responseComplete()
.تأكد من أن لا
Filter
أوServlet
في نفس سلسلة الاستجابة للطلب ، منعت طلب FOFacesServlet
بطريقة ما.إذا كنت تستخدم Primefaces
<p:dialog>
أو أ<p:overlayPanel>
, ثم تأكد من أن لديهم خاصة بهم<h:form>
. لأن هذه المكونات افتراضيًا بواسطة JavaScript تم نقلها إلى نهاية HTML<body>
. لذلك ، إذا كانوا جالسين في الأصل داخل أ<form>
, ، ثم لم يعد يجلسون في أ<form>
. أنظر أيضا P: إجراءات CommandButton لا يعمل داخل P: Dialogعلة في الإطار. على سبيل المثال ، Richfaces لديه "خطأ التحويل"عند استخدام أ
rich:calendar
عنصر واجهة المستخدم مع أdefaultLabel
السمة (أو ، في بعض الحالات ، أrich:placeholder
العناصر الفرعية). يمنع هذا الخطأ طريقة التذرع عندما لا يتم تعيين أي قيمة لتاريخ التقويم. يمكن إنجاز أخطاء إطار التتبع من خلال البدء بمثال عمل بسيط وبناء الصفحة احتياطيًا حتى يتم اكتشاف الأخطاء.
تلميحات تصحيح
في حال كنت لا تزال Stucks ، فقد حان الوقت للتصحيح. في جانب العميل ، اضغط على F12 في WebBrowser لفتح مجموعة أدوات مطور الويب. انقر على وحدة التحكم علامة التبويب لذلك انظر JavaScript Conosle. يجب أن تكون خالية من أي أخطاء JavaScript. يوجد مثال من لقطة الشاشة مثالًا من Chrome يوضح حالة تقديم <f:ajax>
زر التمكين أثناء عدم وجود <h:head>
أعلن (كما هو موضح في النقطة 7 أعلاه).
انقر على شبكة علامة التبويب لرؤية مراقبة حركة المرور HTTP. أرسل النموذج والتحقيق في ما إذا كانت رؤوس الطلب وبيانات النماذج وجنة الاستجابة هي حسب التوقعات. يوجد مثال من لقطة الشاشة مثالاً من Chrom <h:inputText>
وعزباء <h:commandButton>
مع <f:ajax execute="@form" render="@form">
.
(تحذير: عندما تنشر لقطات شاشة من HTTP يطلب رؤوس كما هو أعلاه من بيئة الإنتاج ، ثم تأكد من التدافع/التغلب على أي ملفات تعريف ارتباط للجلسة في لقطة الشاشة لتجنب هجمات الاختطاف في الجلسة!)
في جانب الخادم ، تأكد من بدء تشغيل الخادم في وضع التصحيح. ضع نقطة توقف التصحيح بطريقة من مكون JSF من الاهتمام الذي تتوقع أن يتم استدعاؤه أثناء معالجة النموذج. على سبيل المثال في حالة UICommand
المكون ، سيكون ذلك UICommand#queueEvent()
وفي حالة UIInput
المكون ، سيكون ذلك UIInput#validate()
. مجرد خطوة من خلال تنفيذ التعليمات البرمجية وفحص ما إذا كان التدفق والمتغيرات حسب التوقعات. أسفل لقطة الشاشة هو مثال من مصحح الأخطاء في Eclipse.
نصائح أخرى
إذا كان لديك h:commandLink
هو داخل أ h:dataTable
هناك سبب آخر يجعل h:commandLink
قد لا تعمل:
مصدر البيانات الأساسي الذي يرتبط بـ h:dataTable
يجب أن يكون متاحًا أيضًا في jsf-lifecycle الثاني الذي يتم تشغيله عند النقر فوق الرابط.
لذلك إذا تم طلب المصدر الأساسي للبيانات ، h:commandLink
لا يعمل!
على الرغم من أن إجابتي لا تنطبق بنسبة 100 ٪ ، لكن معظم محركات البحث تجد هذا على أنه أول ضربة ، قررت أن أنشرها مع ذلك: ومع ذلك:
إذا كنت تستخدم Primefaces (أو بعض API مماثل) p:commandButton
أو p:commandLink
, ، من المحتمل أنك نسيت أن تضيف بشكل صريح process="@this"
إلى مكونات الأمر الخاص بك.
كما ينص دليل مستخدم PrimeFaces في القسم 3.18 ، فإن الإعدادات الافتراضية process
و update
كلاهما @form
, ، الذي يعارض إلى حد كبير التخلف عن السداد التي قد تتوقعها من JSF العادي f:ajax
أو ريتشفس ، والتي هي execute="@this"
و render="@none"
على التوالى.
لقد أخذني للتو وقتًا لطفًا لمعرفة ذلك. (... وأعتقد أنه من العملي استخدام الافتراضات التي تختلف عن JSF!)
أود أن أذكر شيئًا آخر يتعلق بـ PrimeFaces p:commandButton
!
عندما تستخدم أ p:commandButton
للإجراء الذي يجب القيام به على الخادم ، لا يمكنك استخدامه type="button"
لأن هذا ل أزرار الضغط التي تستخدم لتنفيذ JavaScript المخصص دون التسبب في طلب AJAX/غير AJAX للخادم.
لهذا الغرض ، يمكنك الاستغناء type
السمة (القيمة الافتراضية هي "submit"
) أو يمكنك استخدامها صراحة type="submit"
.
امل ان يساعد هذا احد!
تعثرت مع هذه القضية بنفسي ووجدت سببًا آخر لهذه المشكلة. إذا لم يكن لديك أساليب Setter في حبة الدعم الخاصة بك للخصائص المستخدمة في *.xhtml ، فإن الإجراء لم يتم الاحتجاج به ببساطة.
لقد واجهت مؤخرًا مشكلة مع UICommand عدم الاحتجاج في تطبيق JSF 1.2 باستخدام مكونات الوجوه الممتدة IBM.
كان لدي زر أمر على صف من DataTable (الإصدار الممتد ، لذلك <hx:datatable>
) ولن يطلق UICommand من صفوف معينة من الطاولة (الصفوف التي لا تطلق النار كانت الصفوف أكبر من حجم عرض الصف الافتراضي).
كان لدي مكون منسول لاختيار عدد الصفوف لعرضه. كانت قيمة دعم هذا الحقل في RequestScope
. كانت البيانات التي تدعم الجدول نفسه في نوع من ViewScope
(في الواقع ، مؤقتا في SessionScope
).
إذا تم زيادة شاشة الصف من خلال التحكم في القيمة التي كانت مرتبطة أيضًا بـ DataTable's rows
السمة ، لا يمكن لأي من الصفوف المعروضة نتيجة لهذا التغيير إطلاق uicommand عند النقر عليه.
وضع هذه السمة في نفس النطاق مثل بيانات الجدول نفسها تحدد المشكلة.
أعتقد أن هذا قد تم الإشارة إليه في balusc #4 أعلاه ، ولكن لم يكن فقط قيمة الجدول يجب أن تكون عرضًا أو جلسة ، ولكن أيضًا السمة التي تتحكم في عدد الصفوف لعرضها على هذا الجدول.
لقد واجهت هذه المشكلة أيضًا وبدأت فقط في الصقل في السبب الجذري بعد فتح وحدة التحكم على شبكة الإنترنت الخاصة بالمتصفح. حتى ذلك ، لم أتمكن من الحصول على أي رسائل خطأ (حتى مع <p:messages>
). أظهرت وحدة التحكم على الويب رمز حالة HTTP 405 يعود من <h:commandButton type="submit" action="#{myBean.submit}">
.
في حالتي ، لدي مزيج من Httpservlet's Vanilla Httpservlet التي تقدم مصادقة OAUTH عبر Facelets Auth0 و JSF والفاصوليا التي تنفذ وجهات نظر التطبيق الخاصة بي ومنطق العمل.
بمجرد أن أعيد إعادة تمهيد web.xml ، وأزلت خوفًا متوسطًا ، فقد نجحت "سحرية".
خلاصة القول ، كانت المشكلة هي أن Servlet المتوسطة كان يستخدم requestDispatcher. .).
في الأساس ، سمح استخدام SendRedirect () لـ JSF "حاوية" بالتحكم في حين أن requestDispatcher.forward () من الواضح أنه لم يكن كذلك.
ما لا أعرفه هو سبب تمكن Facelet من الوصول إلى خصائص الفول ولكن لم يستطع ضبطها ، وهذا يصرخ بوضوح لتفكيكه بمزيج من servlets و JSF ، لكنني آمل أن يساعد هذا شخصًا ما في تجنب عدة ساعات من الرأس- إلى الطاولة.
كان لدي الكثير من المرح في تصحيح قضية حيث أ <h:commandLink>
عمل في richfaces
datatable
رفض إطلاق النار. يستخدم الجدول للعمل في مرحلة ما ولكنه توقف دون سبب واضح. لم أترك أي حجر لم يسبق له مثيل ، فقط لأكتشف أني rich:datatable
كان يستخدم الخطأ rowKeyConverter
التي عادت فارغة التي استخدمها ريتشفس بسعادة كمفاتيح صف. هذا منع بلدي <h:commandLink>
العمل من الحصول على استدعاء.
احتمال واحد آخر: إذا كانت الأعراض هي أن الاحتجاج الأول يعمل ، ولكن لا تفعل ذلك ، فقد تستخدم PrimeFaces 3.x مع JSF 2.2 ، كما هو مفصل هنا: لم يتم إرسال أي Viewstate.
لقد أصلحت مشكلتي في وضع:
<h:commandButton class="btn btn-danger" value = "Remove" action="#{deleteEmployeeBean.delete}"></h:commandButton>
في:
<h:form>
<h:commandButton class="btn btn-danger" value = "Remove" action="#{deleteEmployeeBean.delete}"></h:commandButton>
</h:form>
<ui:composition>
<h:form id="form1">
<p:dialog id="dialog1">
<p:commandButton value="Save" action="#{bean.method1}" /> <!--Working-->
</p:dialog>
</h:form>
<h:form id="form2">
<p:dialog id="dialog2">
<p:commandButton value="Save" action="#{bean.method2}" /> <!--Not Working-->
</p:dialog>
</h:form>
</ui:composition>
لتحل؛
<ui:composition>
<h:form id="form1">
<p:dialog id="dialog1">
<p:commandButton value="Save" action="#{bean.method1}" /> <!-- Working -->
</p:dialog>
<p:dialog id="dialog2">
<p:commandButton value="Save" action="#{bean.method2}" /> <!--Working -->
</p:dialog>
</h:form>
<h:form id="form2">
<!-- .......... -->
</h:form>
</ui:composition>