سؤال

في بعض الأحيان ، عند استخدام <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+ لفتح مجموعة أدوات مطور الويب ثم افتح وحدة التحكم علامة التبويب) ، ثم اعمل من خلال قائمة الأسباب المحتملة أدناه.

الأسباب المحتملة

  1. UICommand و UIInput يجب وضع المكونات داخل UIForm مكون ، على سبيل المثال <h:form> (وبالتالي ليس HTML عادي <form>) ، وإلا لا يمكن إرسال أي شيء إلى الخادم. UICommand يجب ألا يكون المكونات أيضًا type="button" السمة ، وإلا فإنه سيكون زر ميت وهو مفيد فقط لجافا سكريبت onclick. أنظر أيضا كيفية إرسال قيم إدخال النموذج واستدعاء طريقة في JSF Bean و u003Ch:commandButton>لا يبدأ بعد الظهر.

  2. لا يمكنك عش متعددة UIForm مكونات في بعضها البعض. هذا غير قانوني في HTML. سلوك المتصفح غير محدد. احترس من تضمين الملفات! يمكنك استخدام UIForm المكونات بالتوازي ، لكنها لن تعالج بعضها البعض أثناء إرسالها. يجب عليك أيضًا الانتباه إلى "شكل الله" المضاد ؛ تأكد من عدم معالجة/التحقق من صحة جميع المدخلات الأخرى (غير المرئية) في نفس النموذج (مثل وجود مربع حوار مخفي مع المدخلات المطلوبة في نفس النموذج). أنظر أيضا كيف تستعملu003Ch:form> في صفحة JSF؟ شكل واحد؟ أشكال متعددة؟ أشكال متداخلة؟.

  3. لا UIInput يجب أن يكون خطأ التحقق من صحة القيمة/التحويل. يمكنك استخدام <h:messages> لإظهار أي رسائل لا تظهرها أي إدخال خاص <h:message> عناصر. لا تنس تضمين id من <h:messages> في ال <f:ajax render>, ، إن وجدت ، بحيث يتم تحديثها أيضًا على طلبات Ajax. أنظر أيضا H: لا تعرض الرسائل رسائل عند الضغط على P: CommandButton.

  4. لو UICommand أو UIInput يتم وضع المكونات داخل مكون تكرار مثل <h:dataTable>, <ui:repeat>, ، إلخ ، فأنت بحاجة إلى التأكد من ذلك بالضبط value يتم الحفاظ على المكون المتكرر أثناء مرحلة قيم طلب الطلب لطلب إرسال النموذج. سيقوم JSF بتكراره للعثور على الرابط/الزر الذي تم النقر عليه وقيم الإدخال المقدمة. وضع الفول في نطاق العرض و/أو التأكد من تحميل نموذج البيانات في @PostConstruct من الفول (وبالتالي ليس في طريقة getter!) يجب إصلاحه. أنظر أيضا كيف ومتى يجب أن أقوم بتحميل النموذج من قاعدة البيانات لـ H: DataTable.

  5. لو UICommand أو UIInput يتم تضمين المكونات بواسطة مصدر ديناميكي مثل <ui:include src="#{bean.include}">, ، ثم تحتاج إلى التأكد من ذلك بالضبط #{bean.include} يتم الحفاظ على القيمة أثناء عرض وقت إنشاء النموذج. سوف JSF إعادة الاستمرار عليه أثناء بناء شجرة المكون. وضع الفول في نطاق العرض و/أو التأكد من تحميل نموذج البيانات في @PostConstruct من الفول (وبالتالي ليس في طريقة getter!) يجب إصلاحه. أنظر أيضا كيف تتضمن Ajax-Refresh Dynamic المحتوى عن طريق قائمة التنقل؟ (JSF Spa).

  6. ال rendered سمة المكون وجميع والديه و test سمة أي والد <c:if>/<c:when> لا ينبغي التقييم ل false أثناء مرحلة طلب طلب الطلب من طلب إرسال النموذج. ستقوم JSF بإعادة فحصها كجزء من الحماية ضد الطلبات المعلبة/المخترقة. تخزين المتغيرات المسؤولة عن الحالة في أ @ViewScoped الفول أو التأكد من أنك تضع الحالة بشكل صحيح في @PostConstruct من @RequestScoped يجب أن يصلحها الفول. الأمر نفسه ينطبق على disabled سمة المكون ، والتي لا ينبغي تقييمها true أثناء تطبيق مرحلة قيم الطلب. أنظر أيضا لم يتم الاحتجاج بنشاط JSF CommandButton و لا تتم معالجة النموذج في المكون المقدم بشكل مشروط.

  7. ال onclick سمة من UICommand مكون و onsubmit سمة من UIForm يجب ألا يعود المكون false أو تسبب خطأ جافا سكريبت. يجب أن يكون هناك في حالة <h:commandLink> أو <f:ajax> كما لا توجد أخطاء JS مرئية في وحدة التحكم JS في المتصفح. عادةً ما تعطيك رسالة الخطأ الدقيقة بالفعل الإجابة. أنظر أيضا يؤدي إضافة jQuery إلى Primefaces إلى نتائج غير معلنة.

  8. إذا كنت تستخدم AJAX عبر JSF 2.x <f:ajax> أو على سبيل المثال <p:commandXxx>, ، تأكد من أن لديك <h:head> في القالب الرئيسي بدلاً من <head>. وإلا فإن JSF لن تتمكن من تلقائي تلقائيًا ملفات JavaScript اللازمة التي تحتوي على وظائف AJAX. سيؤدي ذلك إلى خطأ JavaScript مثل "Mojarra غير محدد" أو "Primefaces غير محدد" في وحدة التحكم JS في المتصفح. أنظر أيضا H: لا يتم استدعاء CommandLink ActionListener عند استخدامها مع F: Ajax و UI: كرر.

  9. إذا كنت تستخدم Ajax ، وينتهي الأمر بالقيم المقدمة null, ، ثم تأكد من أن UIInput و UICommand يتم تغطية مكونات الاهتمام من قبل <f:ajax execute> أو على سبيل المثال <p:commandXxx process>, ، وإلا فلن يتم تنفيذها/معالجتها. أنظر أيضا قيم النموذج المقدمة لم يتم تحديثها في النموذج عند الإضافةu003Cf:ajax> لu003Ch:commandButton> و فهم عملية/تحديث PrimeFaces و JSF F: سمات تنفيذ/تقديم AJAX.

  10. إذا كانت القيم المقدمة لا تزال تنتهي null, ، وأنت تستخدم CDI لإدارة الفاصوليا ، ثم تأكد من استيراد التعليق التوضيحي للنطاق من الحزمة الصحيحة ، وإلا فإن CDI سوف تتخلف عن @Dependent الذي يعيد بفعالية الفول على كل تقييم واحد للتعبير EL. أنظر أيضا sessionscoped Bean يفقد نطاقه ويتم إعادة إنشاءه طوال الوقت ، تصبح الحقول خالية و ما هو نطاق الفول المدار الافتراضي في تطبيق JSF 2؟

  11. إذا كان أحد الوالدين <h:form> مع ال UICommand يتم تقديم/تحديث الزر قبل طلب AJAX قادمًا من نموذج آخر في نفس الصفحة ، فإن الإجراء الأول سيفشل دائمًا في JSF 2.2 أو أكبر. الإجراءات الثانية واللاحقة ستعمل. هذا ناتج عن وجود خطأ في عرض الحالة التي يتم الإبلاغ عنها على أنها JSF SPEC Issue 790 ومثبت حاليًا في JSF 2.3. بالنسبة لإصدارات JSF القديمة ، تحتاج إلى تحديد معرف <h:form> في ال render التابع <f:ajax>. أنظر أيضا H: CommandButton/H: لا يعمل CommandLink على النقر أولاً ، يعمل فقط على النقر الثاني.

  12. إذا <h:form> لديها enctype="multipart/form-data" تعيين لدعم تحميل الملفات ، ثم تحتاج إلى التأكد من أنك تستخدم على الأقل JSF 2.2 ، أو أن مرشح Servlet المسؤول عن تحليل طلبات multipart/form بشكل صحيح ، وإلا FacesServlet سوف ينتهي الأمر بالحصول على أي معلمات طلب على الإطلاق ، وبالتالي لا تكون قادرًا على تطبيق قيم الطلب. تعتمد كيفية تكوين مثل هذا المرشح على مكون تحميل الملف المستخدم. من أجل توماهوك <t:inputFileUpload>, ، التحقق من هذا الجواب وللأمر <p:fileUpload>, ، التحقق من هذا الجواب. أو ، إذا كنت في الواقع لا تقوم بتحميل ملف على الإطلاق ، فقم بإزالة السمة تمامًا.

  13. تأكد من أن ActionEvent حجة actionListener هو javax.faces.event.ActionEvent وبالتالي لا java.awt.event.ActionEvent, ، وهو ما تشير إليه معظم IDEs كخيار الإكمال التلقائي الأول. عدم وجود حجة خطأ أيضًا إذا كنت تستخدم actionListener="#{bean.method}". إذا كنت لا تريد وسيطة في طريقتك ، فاستخدم actionListener="#{bean.method()}". أو ربما تريد استخدامها بالفعل action بدلاً من actionListener. أنظر أيضا الاختلافات بين العمل و ActionListener.

  14. تأكد من أن لا PhaseListener أو أي EventListener في سلسلة استجابة الطلب ، غيرت دورة حياة JSF لتخطي مرحلة إجراء الاستدعاء على سبيل المثال الاتصال FacesContext#renderResponse() أو FacesContext#responseComplete().

  15. تأكد من أن لا Filter أو Servlet في نفس سلسلة الاستجابة للطلب ، منعت طلب FO FacesServlet بطريقة ما.

  16. إذا كنت تستخدم Primefaces <p:dialog> أو أ <p:overlayPanel>, ثم تأكد من أن لديهم خاصة بهم <h:form>. لأن هذه المكونات افتراضيًا بواسطة JavaScript تم نقلها إلى نهاية HTML <body>. لذلك ، إذا كانوا جالسين في الأصل داخل أ <form>, ، ثم لم يعد يجلسون في أ <form>. أنظر أيضا P: إجراءات CommandButton لا يعمل داخل P: Dialog

  17. علة في الإطار. على سبيل المثال ، Richfaces لديه "خطأ التحويل"عند استخدام أ rich:calendar عنصر واجهة المستخدم مع أ defaultLabel السمة (أو ، في بعض الحالات ، أ rich:placeholder العناصر الفرعية). يمنع هذا الخطأ طريقة التذرع عندما لا يتم تعيين أي قيمة لتاريخ التقويم. يمكن إنجاز أخطاء إطار التتبع من خلال البدء بمثال عمل بسيط وبناء الصفحة احتياطيًا حتى يتم اكتشاف الأخطاء.

تلميحات تصحيح

في حال كنت لا تزال Stucks ، فقد حان الوقت للتصحيح. في جانب العميل ، اضغط على F12 في WebBrowser لفتح مجموعة أدوات مطور الويب. انقر على وحدة التحكم علامة التبويب لذلك انظر JavaScript Conosle. يجب أن تكون خالية من أي أخطاء JavaScript. يوجد مثال من لقطة الشاشة مثالًا من Chrome يوضح حالة تقديم <f:ajax> زر التمكين أثناء عدم وجود <h:head> أعلن (كما هو موضح في النقطة 7 أعلاه).

js console

انقر على شبكة علامة التبويب لرؤية مراقبة حركة المرور HTTP. أرسل النموذج والتحقيق في ما إذا كانت رؤوس الطلب وبيانات النماذج وجنة الاستجابة هي حسب التوقعات. يوجد مثال من لقطة الشاشة مثالاً من Chrom <h:inputText> وعزباء <h:commandButton> مع <f:ajax execute="@form" render="@form">.

network monitor

(تحذير: عندما تنشر لقطات شاشة من HTTP يطلب رؤوس كما هو أعلاه من بيئة الإنتاج ، ثم تأكد من التدافع/التغلب على أي ملفات تعريف ارتباط للجلسة في لقطة الشاشة لتجنب هجمات الاختطاف في الجلسة!)

في جانب الخادم ، تأكد من بدء تشغيل الخادم في وضع التصحيح. ضع نقطة توقف التصحيح بطريقة من مكون JSF من الاهتمام الذي تتوقع أن يتم استدعاؤه أثناء معالجة النموذج. على سبيل المثال في حالة UICommand المكون ، سيكون ذلك UICommand#queueEvent() وفي حالة UIInput المكون ، سيكون ذلك UIInput#validate(). مجرد خطوة من خلال تنفيذ التعليمات البرمجية وفحص ما إذا كان التدفق والمتغيرات حسب التوقعات. أسفل لقطة الشاشة هو مثال من مصحح الأخطاء في Eclipse.

debug server

نصائح أخرى

إذا كان لديك 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>
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top