metodo commandButton/commandLink/azione/ascoltatore ajax non richiamato o valore di input non impostato/aggiornato

StackOverflow https://stackoverflow.com/questions/2118656

Domanda

A volte, quando si utilizza <h:commandLink>, <h:commandButton> O <f:ajax>, IL action, actionListener O listener il metodo associato al tag semplicemente non viene richiamato.Oppure le proprietà del bean non vengono aggiornate con l'invio UIInput valori.

Quali sono le possibili cause e soluzioni a ciò?

È stato utile?

Soluzione

introduzione

Ogni volta che un UICommand componente (<h:commandXxx>, <p:commandXxx>, ecc.) non riesce a richiamare il metodo di azione associato o un UIInput componente (<h:inputXxx>, <p:inputXxxx>, ecc.) non riesce a elaborare i valori inviati e/o aggiorna i valori del modello e non vedi eccezioni e/o avvisi Google nel registro del server, anche quando configuri un gestore di eccezioni Ajax come da Gestione delle eccezioni nelle richieste Ajax JSF, né quando imposti il ​​parametro di contesto di seguito in web.xml,

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

e non vedi nemmeno errori e/o avvisi su Google nella console JavaScript del browser (premi F12 in Chrome/Firefox23+/IE9+ per aprire il set di strumenti per sviluppatori web e quindi aprire il Consolle scheda), quindi consultare l'elenco delle possibili cause riportato di seguito.

Cause possibili

  1. UICommand E UIInput i componenti devono essere posizionati all'interno di un UIForm componente, ad es. <h:form> (e quindi non semplice HTML <form>), altrimenti non sarà possibile inviare nulla al server. UICommand anche i componenti non devono avere type="button" attributo, altrimenti sarà un pulsante morto utile solo per JavaScript onclick.Guarda anche Come inviare valori di input del modulo e richiamare un metodo nel bean JSF E <h:commandButton> non avvia un postback.

  2. Non è possibile nidificare più elementi UIForm componenti l'uno nell'altro.Questo è illegale in HTML.Il comportamento del browser non è specificato.Attenzione ai file include!Puoi usare UIForm componenti in parallelo, ma non si elaboreranno a vicenda durante l'invio.Dovresti anche fare attenzione all'antipattern "God Form";assicurati di non elaborare/convalidare involontariamente tutti gli altri input (invisibili) nella stessa forma (ad es.avere una finestra di dialogo nascosta con gli input richiesti nella stessa forma).Guarda anche Come utilizzare <h:form> nella pagina JSF?Modulo unico?Forme multiple?Forme nidificate?.

  3. NO UIInput dovrebbe essersi verificato un errore di convalida/conversione del valore.Puoi usare <h:messages> per mostrare tutti i messaggi che non vengono mostrati da alcun input specifico <h:message> componenti.Non dimenticare di includere il id Di <h:messages> nel <f:ajax render>, se presente, in modo che venga aggiornato anche sulle richieste Ajax.Guarda anche h:messages non visualizza i messaggi quando viene premuto p:commandButton.

  4. Se UICommand O UIInput i componenti sono posizionati all'interno di un componente iterativo come <h:dataTable>, <ui:repeat>, ecc., devi assicurarti che sia esattamente lo stesso value del componente iterativo è stato preservato durante la fase di applicazione dei valori della richiesta della richiesta di invio del modulo.JSF lo ripeterà per trovare il collegamento/pulsante cliccato e i valori di input inviati.Inserendo il bean nell'ambito della vista e/o assicurandosi di caricare il modello dati @PostConstruct del bean (e quindi non in un metodo getter!) dovrebbe risolverlo.Guarda anche Come e quando dovrei caricare il modello dal database per h:dataTable.

  5. Se UICommand O UIInput i componenti sono inclusi da un'origine dinamica come <ui:include src="#{bean.include}">, allora devi assicurarti che sia esattamente lo stesso #{bean.include} il valore viene conservato durante la fase di creazione della vista della richiesta di invio del modulo.JSF lo rieseguirà durante la costruzione dell'albero dei componenti.Inserendo il bean nell'ambito della vista e/o assicurandosi di caricare il modello dati @PostConstruct del bean (e quindi non in un metodo getter!) dovrebbe risolverlo.Guarda anche Come aggiornare Ajax con inclusione dinamica del contenuto tramite il menu di navigazione?(JSF SPA).

  6. IL rendered attributo del componente e di tutti i suoi genitori e il file test attributo di qualsiasi genitore <c:if>/<c:when> non dovrebbe valutare false durante la fase di applicazione dei valori della richiesta del modulo di richiesta di invio.JSF lo ricontrollerà come parte della salvaguardia contro richieste manomesse/hackerate.Memorizzare le variabili responsabili della condizione in a @ViewScoped bean o assicurandoti di preinizializzare correttamente la condizione in @PostConstruct di un @RequestScoped bean dovrebbe risolverlo.Lo stesso vale per il disabled attributo del componente, che non dovrebbe valutare true durante la fase di applicazione dei valori di richiesta.Guarda anche Azione CommandButton JSF non richiamata E L'invio del modulo nel componente visualizzato in modo condizionale non viene elaborato.

  7. IL onclick attributo del UICommand componente e il onsubmit attributo del UIForm il componente non dovrebbe tornare false o causare un errore JavaScript.Dovrebbe esserci in caso di <h:commandLink> O <f:ajax> inoltre non saranno visibili errori JS nella console JS del browser.Di solito cercare su Google il messaggio di errore esatto ti darà già la risposta.Guarda anche L'aggiunta di jQuery a PrimeFaces genera errori di tipo non rilevati.

  8. Se stai utilizzando Ajax tramite JSF 2.x <f:ajax> o ad es.PrimeFaces <p:commandXxx>, assicurati di avere un file <h:head> nel modello principale invece che nel file <head>.Altrimenti JSF non sarà in grado di includere automaticamente i file JavaScript necessari che contengono le funzioni Ajax.Ciò comporterebbe un errore JavaScript come "mojarra non è definito" o "PrimeFaces non è definito" nella console JS del browser.Guarda anche h:commandLink actionlistener non viene richiamato se utilizzato con f:ajax e ui:repeat.

  9. Se stai utilizzando Ajax e i valori inviati finiscono per essere null, quindi assicurati che UIInput E UICommand i componenti di interesse sono coperti da <f:ajax execute> o ad es. <p:commandXxx process>, altrimenti non verranno eseguiti/elaborati.Guarda anche I valori del modulo inviato non vengono aggiornati nel modello quando si aggiunge <f:ajax> a <h:commandButton> E Comprensione del processo/aggiornamento di PrimeFaces e degli attributi di esecuzione/rendering di JSF f:ajax.

  10. Se i valori inviati risultano ancora null, e stai utilizzando CDI per gestire i bean, quindi assicurati di importare l'annotazione dell'ambito dal pacchetto corretto, altrimenti CDI verrà impostato automaticamente su @Dependent che ricrea efficacemente il bean su ogni singola valutazione dell'espressione EL.Guarda anche Il bean @SessionScoped perde l'ambito e viene ricreato continuamente, i campi diventano nulli E Qual è l'ambito Managed Bean predefinito in un'applicazione JSF 2?

  11. Se un genitore del <h:form> con il UICommand Il pulsante è stato precedentemente renderizzato/aggiornato da una richiesta Ajax proveniente da un altro modulo nella stessa pagina, la prima azione fallirà sempre in JSF 2.2 o versioni precedenti.La seconda e le successive azioni funzioneranno.Ciò è causato da un bug nella gestione dello stato di visualizzazione segnalato come Edizione 790 delle specifiche JSF e attualmente risolto in JSF 2.3.Per le versioni JSF precedenti, è necessario specificare esplicitamente l'ID del file <h:form> nel render del <f:ajax>.Guarda anche h:commandButton/h:commandLink non funziona al primo clic, funziona solo al secondo clic.

  12. Se la <h:form> ha enctype="multipart/form-data" impostato per supportare il caricamento dei file, devi assicurarti di utilizzare almeno JSF 2.2 o che il filtro servlet responsabile dell'analisi delle richieste multipart/form-data sia configurato correttamente, altrimenti il FacesServlet finirà per non ottenere alcun parametro di richiesta e quindi non sarà in grado di applicare i valori della richiesta.La modalità di configurazione di tale filtro dipende dal componente di caricamento file utilizzato.Per Tomahawk <t:inputFileUpload>, controllo questa risposta e per PrimeFaces <p:fileUpload>, controllo questa risposta.Oppure, se in realtà non stai caricando affatto un file, rimuovi del tutto l'attributo.

  13. Assicurati che il ActionEvent argomento di actionListener è un javax.faces.event.ActionEvent e quindi no java.awt.event.ActionEvent, che è ciò che la maggior parte degli IDE suggerisce come prima opzione di completamento automatico.Anche non avere argomenti è sbagliato se lo usi actionListener="#{bean.method}".Se non vuoi un argomento nel tuo metodo, usa actionListener="#{bean.method()}".O forse vuoi davvero usarlo action invece di actionListener.Guarda anche Differenze tra action e actionListener.

  14. Assicurati che no PhaseListener o qualsiasi EventListener nella catena richiesta-risposta è stato modificato il ciclo di vita JSF per saltare la fase di azione di invocazione, ad esempio chiamando FacesContext#renderResponse() O FacesContext#responseComplete().

  15. Assicurati che no Filter O Servlet nella stessa catena richiesta-risposta ha bloccato la richiesta del FacesServlet in qualche modo.

  16. Se stai utilizzando un PrimeFaces <p:dialog> o a <p:overlayPanel>, quindi assicurati che ne abbiano uno proprio <h:form>.Perché questi componenti vengono spostati per impostazione predefinita da JavaScript alla fine dell'HTML <body>.Quindi, se originariamente fossero seduti all'interno di a <form>, allora ora non si siederebbero più in a <form>.Guarda anche L'azione p:commandbutton non funziona all'interno di p:dialog

  17. Bug nel framework.Ad esempio, RichFaces ha un "errore di conversione" quando si utilizza a rich:calendar Elemento dell'interfaccia utente con a defaultLabel attributo (o, in alcuni casi, a rich:placeholder sottoelemento).Questo bug impedisce che il metodo bean venga richiamato quando non è impostato alcun valore per la data del calendario.È possibile tracciare i bug del framework iniziando con un semplice esempio funzionante e costruendo la pagina fino a quando non viene scoperto il bug.

Suggerimenti per il debug

Nel caso in cui continui a bloccarti, è ora di eseguire il debug.Sul lato client, premi F12 nel browser web per aprire il set di strumenti per sviluppatori web.Clicca il Consolle scheda quindi consulta la console JavaScript.Dovrebbe essere privo di errori JavaScript.Lo screenshot seguente è un esempio di Chrome che dimostra il caso di invio di un file <f:ajax> pulsante abilitato pur non avendo <h:head> dichiarato (come descritto al punto 7 sopra).

js console

Clicca il Rete scheda per visualizzare il monitoraggio del traffico HTTP.Invia il modulo e verifica se le intestazioni della richiesta, i dati del modulo e il corpo della risposta sono conformi alle aspettative.Lo screenshot seguente è un esempio di Chrome che dimostra un invio Ajax riuscito di un modulo semplice con un singolo <h:inputText> e un singolo <h:commandButton> con <f:ajax execute="@form" render="@form">.

network monitor

(avvertimento:quando pubblichi screenshot da intestazioni di richiesta HTTP come sopra da un ambiente di produzione, assicurati di codificare/offuscare eventuali cookie di sessione nello screenshot per evitare attacchi di dirottamento della sessione!)

Sul lato server, assicurati che il server sia avviato in modalità debug.Inserisci un punto di interruzione di debug in un metodo del componente JSF di interesse che prevedi venga chiamato durante l'elaborazione dell'invio del modulo.Per esempio.in caso di UICommand componente, quello sarebbe UICommand#queueEvent() e in caso di UIInput componente, quello sarebbe UIInput#validate().Basta seguire l'esecuzione del codice e verificare se il flusso e le variabili sono conformi alle aspettative.Lo screenshot seguente è un esempio del debugger di Eclipse.

debug server

Altri suggerimenti

Se il h:commandLink è all'interno di un h:dataTable c'è un altro motivo per cui il h:commandLink potrebbe non funzionare:

Il sottostante di dati-source che è destinato al h:dataTable deve anche essere disponibile nel secondo JSF-ciclo di vita che viene attivato quando il collegamento viene cliccato.

Quindi, se il sottostante i dati-sorgente è richiesta ambito, il h:commandLink non funziona!

Mentre la mia risposta non è applicabile al 100%, ma la maggior parte dei motori di ricerca trovare questo come il primo colpo, ho deciso di postare ma la vera:

Se stai usando primefaces (o qualche API simili) p:commandButton o p:commandLink, è probabile che si è dimenticato di aggiungere in modo esplicito process="@this" ai componenti di comando.

Come il Manuale dell'utente di primefaces afferma nel paragrafo 3.18, le impostazioni predefinite per process e update sono entrambi @form, che si oppone più o meno i valori di default si potrebbe aspettare dalla pianura f:ajax JSF o RichFaces, che sono rispettivamente execute="@this" e render="@none".

Basta che mi ha preso un tempo luuungo per scoprirlo. (... e penso che sia piuttosto unclever usare le impostazioni che sono diverse da JSF!)

vorrei ricordare una cosa che riguarda p:commandButton di primefaces!

Quando si utilizza una p:commandButton per l'azione che deve essere fatto sul server, non è possibile utilizzare type="button" perché questo è per Pulsanti che vengono utilizzati per eseguire JavaScript personalizzato senza causare un Ajax / non ajax richiesta al server.

A questo scopo, si può fare a meno l'attributo type (valore di default è "submit") oppure è possibile utilizzare in modo esplicito type="submit".

Spero che questo vi aiuterà qualcuno!

è rimasto bloccato con questo problema me stesso e ho trovato un altro motivo di questo problema. Se non si dispone di metodi setter nel backing bean per le proprietà utilizzate nel vostro * .xhtml, allora l'azione non è semplicemente invocato.

Di recente ho incontrato un problema con un UICommand non invocare in un'applicazione JSF 1.2 utilizzando IBM esteso Faces Componenti.

ho avuto un pulsante di comando su una fila di un DataTable (la versione estesa, in modo <hx:datatable>) e l'UICommand non vorrei sparare da alcune righe della tabella (le righe che non sarebbe il fuoco erano le righe superiore del display riga predefinita dimensioni).

avevo un componente discesa per selezionare il numero di righe da visualizzare. Il valore sostegno questo campo era in RequestScope. I dati che sostengono la tabella stessa era in una sorta di ViewScope (in realtà, temporaneamente nella SessionScope).

Se il display riga è stata aumentata tramite il controllo il cui valore è stato anche legato all'attributo rows della DataTable, nessuno dei file visualizzato come risultato di questo cambiamento potrebbe scattare l'UICommand quando si fa clic.

Immissione questo attributo nello stesso ambito come dati tabella stessa fissato il problema.

Credo che questo si allude al precedente BalusC # 4, ma non solo il valore della tabella deve essere vista o con scope di sessione, ma anche l'attributo che controlla il numero di righe da visualizzare su quel tavolo.

Ho avuto questo problema come bene e veramente solo iniziato a perfezionare nella causa principale dopo l'apertura console web del browser. Fino a quel, non ero in grado di ottenere eventuali messaggi di errore (anche con <p:messages>). La console web ha mostrato un codice di stato HTTP 405 di ritorno dalla <h:commandButton type="submit" action="#{myBean.submit}">.

Nel mio caso, ho un mix di vaniglia HttpServlet sta fornendo l'autenticazione OAuth via Auth0 e JSF facelets e fagioli che svolgono miei punti di vista dell'applicazione e la logica di business.

Una volta che ho refactoring il mio web.xml, e rimosso un middle-man-servlet, poi "magicamente" ha funzionato.

In conclusione, il problema era che la metà-uomo-servlet stava usando RequestDispatcher.forward (...) per reindirizzare dall'ambiente HttpServlet per l'ambiente JSF mentre il servlet di essere chiamato prima di esso è stato riorientando con HttpServletResponse.sendRedirect (...).

In sostanza, utilizzando sendRedirect () accettati JSF "contenitore" per assumere il controllo che RequestDispatcher.forward () non era ovviamente.

Quello che non so è il motivo per cui la facelet è stato in grado di accedere alle proprietà di fagioli, ma non riusciva a impostare, e questo chiaramente urla per fare via con il mix di servlet e JSF, ma spero che questo aiuta qualcuno evitare molte ore di testa-a-tavolo-banging.

Ho avuto un sacco di divertimento debug un problema in cui l'azione di un <h:commandLink> in richfaces datatable rifiutato di sparare. La tabella utilizzata per lavorare ad un certo punto, ma fermato per nessun motivo apparente. Ho lasciato nulla di intentato, solo per scoprire che il mio rich:datatable stava usando il rowKeyConverter sbagliata che ha restituito i valori nulli che RichFaces felicemente utilizzati come chiavi di fila. Ciò ha impedito la mia azione <h:commandLink> da ottenere chiamato.

Ancora una possibilità: se il sintomo è che la prima invocazione funziona, ma quelle successive non lo fanno, si può utilizzare primefaces 3.x con JSF 2.2, come dettagliato qui: No ViewState viene inviata .

Ho risolto il mio problema con l'immissione del:

<h:commandButton class="btn btn-danger" value = "Remove" action="#{deleteEmployeeBean.delete}"></h:commandButton>

A:

<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>

Per risolvere;

<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>
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top