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
-
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 .
-
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? .
-
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 .
-
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? .
-
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) .
-
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
-
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 .
-
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 .
-
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 .
-
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?
-
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 .
-
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.
-
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 .
-
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()
.
-
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 .
-
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
-
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).
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">
.
(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.