370 Stimmen

commandButton/commandLink/ajax action/listener Methode nicht aufgerufen oder Eingabewert nicht gesetzt/aktualisiert

Manchmal, wenn man <h:commandLink> , <h:commandButton> o <f:ajax> , le action , actionListener o listener Methode, die mit dem Tag verknüpft ist, wird einfach nicht aufgerufen. Oder die Bean-Eigenschaften werden nicht mit den übermittelten Daten aktualisiert. UIInput Werte.

Was sind die möglichen Ursachen und Lösungen dafür?

725voto

BalusC Punkte 1034465

Einführung

Wann immer ein UICommand Komponente ( <h:commandXxx> , <p:commandXxx> usw.) kann die zugehörige Aktionsmethode nicht aufgerufen werden, oder ein UIInput Komponente ( <h:inputXxx> , <p:inputXxxx> usw.) kann die übermittelten Werte nicht verarbeiten und/oder die Modellwerte aktualisieren, und Sie sehen keine googlbaren Ausnahmen und/oder Warnungen im Serverprotokoll, auch nicht, wenn Sie einen Ajax-Exception-Handler gemäß Ausnahmebehandlung in JSF-Ajax-Anfragen noch wenn Sie unter Kontextparameter in web.xml ,

<context-param>
    <param-name>javax.faces.PROJECT_STAGE</param-name>
    <param-value>Development</param-value>
</context-param>

und Sie sehen auch keine googlbaren Fehler und/oder Warnungen in der JavaScript-Konsole des Browsers (drücken Sie F12 in Chrome/Firefox23+/IE9+, um das Webentwickler-Toolset zu öffnen und öffnen Sie dann die Konsole Registerkarte) und gehen Sie dann die unten stehende Liste der möglichen Ursachen durch.

Mögliche Ursachen

  1. UICommand y UIInput Komponenten müssen innerhalb einer UIForm Komponente, z.B. <h:form> ( <form> ), sonst kann nichts an den Server gesendet werden. UICommand Komponenten dürfen auch nicht über type="button" Attribut, andernfalls wird es eine tote Schaltfläche sein, die nur für JavaScript nützlich ist onclick . Siehe auch Senden von Formulareingabewerten und Aufrufen einer Methode in einer JSF-Bohne y <h:commandButton> löst kein Postback aus .

  2. Sie können nicht mehrere UIForm Komponenten ineinander. Dies ist in HTML illegal. Das Verhalten des Browsers ist nicht spezifiziert. Vorsicht bei Include-Dateien! Sie können UIForm Komponenten parallel zueinander, aber sie verarbeiten sich nicht gegenseitig während der Übertragung. Sie sollten auch auf das "God Form"-Antipattern achten; stellen Sie sicher, dass Sie nicht unbeabsichtigt alle anderen (unsichtbaren) Eingaben im selben Formular verarbeiten/validieren (z.B. einen versteckten Dialog mit erforderlichen Eingaben im selben Formular). Siehe auch Wie verwendet man <h:form> in einer JSF-Seite? Einzelnes Formular? Mehrere Formulare? Verschachtelte Formulare? .

  3. Nein UIInput sollte ein Fehler bei der Validierung/Umwandlung von Werten aufgetreten sein. Sie können verwenden <h:messages> um alle Meldungen anzuzeigen, die nicht durch eine eingabespezifische Meldung angezeigt werden <h:message> Komponenten. Vergessen Sie nicht, die id von <h:messages> en el <f:ajax render> damit sie auch bei Ajax-Anfragen aktualisiert wird. Siehe auch h:messages zeigt keine Nachrichten an, wenn p:commandButton gedrückt wird .

  4. Si UICommand o UIInput Komponenten werden innerhalb einer sich wiederholenden Komponente wie <h:dataTable> , <ui:repeat> usw., dann müssen Sie sicherstellen, dass genau die gleichen value der Iterationskomponente wird während der Phase "apply request values" der Formularübermittlungsanfrage beibehalten. JSF wird es wiederholen, um den angeklickten Link/die angeklickte Schaltfläche und die übermittelten Eingabewerte zu finden. Wenn Sie die Bean in den View-Scope setzen und/oder sicherstellen, dass Sie das Datenmodell in @PostConstruct der Bean (und damit nicht in einer Getter-Methode!) sollte das Problem beheben. Siehe auch Wie und wann sollte ich das Modell für h:dataTable aus der Datenbank laden? .

  5. Si UICommand o UIInput Komponenten werden von einer dynamischen Quelle wie <ui:include src="#{bean.include}"> dann müssen Sie sicherstellen, dass genau die gleichen #{bean.include} wird während der Erstellungszeit der Ansicht des Formulars beibehalten. JSF wird ihn während der Erstellung des Komponentenbaums erneut ausführen. Wenn Sie die Bean in den View-Scope setzen und/oder sicherstellen, dass Sie das Datenmodell in @PostConstruct der Bohne (und damit nicht in einer Getter-Methode!) sollte das Problem beheben. Siehe auch Wie ajax-refresh dynamischen Inhalt von Navigationsmenü enthalten? (JSF SPA) .

  6. Les rendered Attribut der Komponente und aller ihrer Eltern sowie das test Attribut eines beliebigen übergeordneten <c:if> / <c:when> sollte nicht zu false während der Phase "apply request values" des Formulars "submit request". JSF prüft sie erneut als Teil des Schutzes gegen manipulierte/gehackte Anfragen. Die Speicherung der für die Bedingung verantwortlichen Variablen in einer @ViewScoped Bohne oder stellen Sie sicher, dass Sie die Bedingung ordnungsgemäß in @PostConstruct eines @RequestScoped Bohne beheben sollte. Das gleiche gilt für die disabled y readonly Attribute der Komponente, die nicht zu true während der Phase der Anwendung der angeforderten Werte. Siehe auch JSF CommandButton-Aktion wird nicht aufgerufen , Formularabgabe in bedingt gerenderter Komponente wird nicht verarbeitet , h:commandButton funktioniert nicht, sobald ich es in eine <h:panelGroup rendered> einpacke y JSF zwingen, schreibgeschützte/deaktivierte Eingabekomponenten trotzdem zu verarbeiten, zu validieren und zu aktualisieren

  7. Les onclick Attribut des UICommand Komponente und die Komponente onsubmit Attribut des UIForm Komponente sollte nicht zurückkehren false oder einen JavaScript-Fehler verursachen. Es sollte im Falle von <h:commandLink> o <f:ajax> auch keine JS-Fehler in der JS-Konsole des Browsers sichtbar sein. Wenn Sie die genaue Fehlermeldung googeln, erhalten Sie in der Regel bereits die Antwort. Siehe auch Manuelles Hinzufügen / Laden von jQuery mit PrimeFaces führt zu Uncaught TypeErrors .

  8. Wenn Sie Ajax über JSF 2.x verwenden <f:ajax> oder z.B. PrimeFaces <p:commandXxx> stellen Sie sicher, dass Sie eine <h:head> in der Master-Vorlage anstelle der <head> . Andernfalls ist JSF nicht in der Lage, die erforderlichen JavaScript-Dateien, die die Ajax-Funktionen enthalten, automatisch einzubinden. Dies würde zu einem JavaScript-Fehler wie "mojarra ist nicht definiert" oder "PrimeFaces ist nicht definiert" in der JS-Konsole des Browsers führen. Siehe auch h:commandLink actionlistener wird bei Verwendung mit f:ajax und ui:repeat nicht aufgerufen .

  9. Wenn Sie Ajax verwenden, und die übermittelten Werte am Ende als null dann stellen Sie sicher, dass die UIInput y UICommand Komponenten von Interesse werden von der <f:ajax execute> oder z.B. <p:commandXxx process> sonst werden sie nicht ausgeführt/verarbeitet. Siehe auch Übermittelte Formularwerte werden im Modell nicht aktualisiert, wenn <f:ajax> zu <h:commandButton> hinzugefügt wird y Verständnis von PrimeFaces process/update und JSF f:ajax execute/render attributes .

  10. Wenn die übermittelten Werte immer noch als null und Sie CDI verwenden, um Beans zu verwalten, dann stellen Sie sicher, dass Sie die Scope-Annotation aus dem richtigen Paket importieren, sonst wird CDI standardmäßig auf @Dependent was die Bohne bei jeder einzelnen Auswertung des EL-Ausdrucks neu erstellt. Siehe auch @SessionScoped bean verliert an Umfang und wird ständig neu erstellt, Felder werden null y Was ist der standardmäßige Managed Bean Scope in einer JSF 2-Anwendung?

  11. Wenn ein Elternteil des <h:form> mit dem UICommand Schaltfläche zuvor durch eine Ajax-Anforderung gerendert/aktualisiert wurde, die von einem anderen Formular auf derselben Seite stammt, wird die erste Aktion in JSF 2.2 oder älter immer fehlschlagen. Die zweite und die folgenden Aktionen funktionieren. Dies wird durch einen Fehler in der Behandlung des Ansichtszustands verursacht, der wie folgt gemeldet wird JSF-Spezifikation Ausgabe 790 und derzeit in JSF 2.3 behoben. Bei älteren JSF-Versionen müssen Sie explizit die ID der <h:form> en el render der <f:ajax> . Siehe auch h:commandButton/h:commandLink funktioniert nicht beim ersten Klick, funktioniert erst beim zweiten Klick .

  12. Wenn die <h:form> a enctype="multipart/form-data" gesetzt ist, um das Hochladen von Dateien zu unterstützen, müssen Sie sicherstellen, dass Sie mindestens JSF 2.2 verwenden oder dass der Servlet-Filter, der für das Parsen von multipart/form-data-Anfragen zuständig ist, richtig konfiguriert ist, da sonst die FacesServlet keine Anforderungsparameter erhalten und somit nicht in der Lage sind, die Anforderungswerte anzuwenden. Wie ein solcher Filter zu konfigurieren ist, hängt von der verwendeten Datei-Upload-Komponente ab. Für Tomahawk <t:inputFileUpload> , prüfen diese Antwort und für PrimeFaces <p:fileUpload> , prüfen diese Antwort . Oder, wenn Sie gar keine Datei hochladen wollen, entfernen Sie das Attribut ganz.

  13. Stellen Sie sicher, dass die ActionEvent Argument von actionListener ist ein javax.faces.event.ActionEvent und somit nicht java.awt.event.ActionEvent , was die meisten IDEs als 1. Autovervollständigungsoption vorschlagen. Kein Argument zu haben ist auch falsch, wenn Sie actionListener="#{bean.method}" . Wenn Sie kein Argument in Ihrer Methode haben wollen, verwenden Sie actionListener="#{bean.method()}" . Oder vielleicht wollen Sie tatsächlich die action anstelle von actionListener . Siehe auch Unterschiede zwischen action und actionListener .

  14. Stellen Sie sicher, dass keine PhaseListener oder jede EventListener in der Anfrage-Antwort-Kette hat den JSF-Lebenszyklus dahingehend geändert, dass die Phase des Aufrufs der Aktion übersprungen wird, indem zum Beispiel FacesContext#renderResponse() o FacesContext#responseComplete() .

  15. Stellen Sie sicher, dass keine Filter o Servlet in der gleichen Anfrage-Antwort-Kette die Anfrage für den FacesServlet irgendwie. Zum Beispiel, Login/Sicherheitsfilter wie Spring Security. Insbesondere bei Ajax-Anfragen, die standardmäßig ohne UI-Feedback enden würden. Siehe auch Spring Security 4 und PrimeFaces 5 AJAX-Anfrageverarbeitung .

  16. Wenn Sie eine PrimeFaces <p:dialog> oder eine <p:overlayPanel> dann stellen Sie sicher, dass sie ihre eigenen <h:form> . Denn diese Komponenten werden standardmäßig von JavaScript an das Ende von HTML verschoben <body> . Wenn sie also ursprünglich in einer <form> dann würden sie jetzt nicht mehr in einem <form> . Siehe auch p:commandbutton Aktion funktioniert nicht innerhalb von p:dialog

  17. Fehler im Framework. Zum Beispiel hat RichFaces einen " Umwandlungsfehler " bei Verwendung einer rich:calendar UI-Element mit einer defaultLabel Attribut (oder, in einigen Fällen, ein rich:placeholder Unterelement). Dieser Fehler verhindert, dass die Bean-Methode aufgerufen wird, wenn kein Wert für das Kalenderdatum festgelegt ist. Das Aufspüren von Framework-Fehlern kann erreicht werden, indem man mit einem einfachen funktionierenden Beispiel beginnt und die Seite wieder aufbaut, bis der Fehler entdeckt wird.

Hinweise zur Fehlersuche

Falls Sie immer noch Probleme haben, ist es Zeit für eine Fehlersuche. Drücken Sie auf der Client-Seite im Webbrowser die Taste F12, um das Toolset für Webentwickler zu öffnen. Klicken Sie auf die Konsole und sehen Sie sich die JavaScript-Konsole an. Es sollten keine JavaScript-Fehler vorhanden sein. Der folgende Screenshot zeigt ein Beispiel aus Chrome, das den Fall der Übermittlung einer <f:ajax> aktivierte Taste, ohne dass die <h:head> erklärt (wie unter Punkt 7 beschrieben).

js console

Klicken Sie auf die Netzwerk um den HTTP-Verkehrsmonitor zu sehen. Senden Sie das Formular ab und prüfen Sie, ob die Header der Anfrage, die Formulardaten und der Antwortkörper den Erwartungen entsprechen. Der folgende Screenshot ist ein Beispiel aus Chrome, das eine erfolgreiche Ajax-Übermittlung eines einfachen Formulars mit einer einzigen <h:inputText> und eine einzige <h:commandButton> con <f:ajax execute="@form" render="@form"> .

network monitor

(Warnung: Wenn Sie Screenshots von HTTP-Request-Headern wie oben aus einer Produktionsumgebung posten, dann stellen Sie sicher, dass Sie alle Session-Cookies im Screenshot verschlüsseln/verschleiern, um Session-Hijacking-Angriffe zu vermeiden).

Stellen Sie auf der Serverseite sicher, dass der Server im Debug-Modus gestartet ist. Setzen Sie einen Debug-Haltepunkt in eine Methode der JSF-Komponente, von der Sie erwarten, dass sie während der Verarbeitung der Formularübermittlung aufgerufen wird. Z.B. im Fall von UICommand Komponente, das wäre UICommand#queueEvent() und im Falle von UIInput Komponente, das wäre UIInput#validate() . Gehen Sie einfach schrittweise durch die Codeausführung und prüfen Sie, ob der Ablauf und die Variablen den Erwartungen entsprechen. Der folgende Screenshot ist ein Beispiel aus dem Debugger von Eclipse.

debug server

56voto

jbandi Punkte 16069

Wenn Ihr h:commandLink ist innerhalb einer h:dataTable Es gibt einen weiteren Grund, warum die h:commandLink möglicherweise nicht funktionieren:

Die zugrunde liegende Datenquelle, die mit dem h:dataTable muss auch im zweiten JSF-Lebenszyklus verfügbar sein, der ausgelöst wird, wenn der Link angeklickt wird.

Wenn also die zugrunde liegende Datenquelle anforderungsabhängig ist, wird die h:commandLink funktioniert nicht!

33voto

Kawu Punkte 13120

Meine Antwort ist zwar nicht zu 100 % zutreffend, aber die meisten Suchmaschinen finden sie als ersten Treffer, so dass ich mich entschlossen habe, sie dennoch zu veröffentlichen:

Wenn Sie Folgendes verwenden PrimeFaces (oder eine ähnliche API) p:commandButton o p:commandLink haben Sie wahrscheinlich vergessen, ausdrücklich hinzuzufügen process="@this" zu Ihren Befehlskomponenten.

Wie im PrimeFaces-Benutzerhandbuch in Abschnitt 3.18 beschrieben, sind die Standardeinstellungen für process y update sind beide @form die den Standardeinstellungen, die man von JSF erwarten könnte, ziemlich entgegengesetzt sind f:ajax oder RichFaces, die execute="@this" y render="@none" beziehungsweise.

Ich habe nur sehr lange gebraucht, um das herauszufinden. (... und ich denke, es ist ziemlich unclever, Standardeinstellungen zu verwenden, die sich von JSF unterscheiden!)

12voto

akelec Punkte 3425

Ich möchte noch eine Sache erwähnen, die die Primefaces betrifft p:commandButton !

Wenn Sie eine p:commandButton für die Aktion, die auf dem Server durchgeführt werden muss, können Sie nicht verwenden type="button" denn das ist für Drucktasten die verwendet werden, um benutzerdefiniertes Javascript auszuführen, ohne eine Ajax/Non-Ajax-Anfrage an den Server zu stellen.

Zu diesem Zweck können Sie auf die type Attribut (Standardwert ist "submit" ) oder Sie können explizit die Option type="submit" .

Hoffentlich hilft das jemandem!

5voto

Dnavir Punkte 526

Ich bin selbst mit diesem Problem konfrontiert und habe eine weitere Ursache für dieses Problem gefunden. Wenn Sie in Ihrer Backing Bean keine Setter-Methoden für die in Ihrer *.xhtml verwendeten Eigenschaften haben, wird die Aktion einfach nicht aufgerufen.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X