commandButton / commandLink / action ajax / méthode d'écouteur pas appelé ou la valeur d'entrée non mis / mise à jour

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

Question

Parfois, lorsque vous utilisez <h:commandLink>, <h:commandButton> ou <f:ajax>, le action, actionListener ou méthode listener associée à l'étiquette sont tout simplement pas être invoquée. Ou, les propriétés de haricots ne sont pas mis à jour avec des valeurs de UIInput soumises.

Quelles sont les causes et solutions possibles pour cela?

Était-ce utile?

La solution

Introduction

Chaque fois qu'un composant UICommand (de <h:commandXxx>, <p:commandXxx>, etc) ne parvient pas à appeler la méthode d'action associée, ou un composant UIInput (<h:inputXxx>, <p:inputXxxx>, etc) ne parvient pas à traiter les valeurs soumises et / ou mettre à jour les valeurs de modèle, et vous aren « t voir des exceptions googlable et / ou mises en garde dans le journal du serveur, pas non plus lorsque vous configurez un gestionnaire d'exception ajax comme par gestion des exceptions dans les demandes de ajax JSF , ni lorsque vous définissez ci-dessous paramètre de contexte dans web.xml,

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

et vous aussi ne voyez pas des erreurs googlable et / ou mises en garde dans la console JavaScript du navigateur (appuyez sur F12 dans Chrome / Firefox23 + / IE9 + pour ouvrir le jeu d'outils de développeur Web, puis ouvrez le fichier Console onglet), travailler ensuite dans la liste ci-dessous des causes possibles.

Causes possibles

  1. Composants UICommand et UIInput doivent être placés à l'intérieur d'un composant UIForm, par exemple, <h:form> (et donc pas simple HTML <form>), sinon rien ne peut être envoyé au serveur. composants UICommand doivent également ne pas avoir l'attribut type="button", sinon ce sera un bouton mort qui est utile pour onclick JavaScript. Voir aussi Comment envoyer le formulaire valeurs d'entrée et appeler une méthode dans bean JSF et fait pas lancer un postback.

  2. Vous ne pouvez pas imbriquer plusieurs composants UIForm dans l'autre. Cette pratique est illégale en HTML. Le comportement du navigateur est non spécifiée. Méfiez-vous avec inclure des fichiers! Vous pouvez utiliser les composants UIForm en parallèle, mais ils ne traitera pas les uns des autres au cours de présenter. Vous devriez également regarder avec antimodèle « Dieu formulaire »; assurez-vous que vous ne traitez pas sans le vouloir / valider toutes les autres entrées (invisibles) dans la même forme (par exemple une boîte de dialogue ayant caché avec les entrées nécessaires sous la forme même). Voir aussi Comment utiliser dans la page JSF? Formulaire unique? Formes multiples? formes emboîtées? .

  3. Pas d'erreur de validation / de conversion de valeur UIInput aurait dû se produire. Vous pouvez utiliser <h:messages> pour afficher les messages qui ne sont pas représentés par des composants spécifiques à l'entrée <h:message>. Ne pas oublier d'inclure le id de <h:messages> dans le <f:ajax render>, le cas échéant, de sorte qu'il sera mis à jour et sur les demandes ajax. Voir aussi h: les messages n'affiche pas les messages lorsque p: commandButton est emboutie .

  4. Si les composants de UICommand ou UIInput sont placés à l'intérieur d'un composant itérer comme <h:dataTable>, <ui:repeat>, etc, alors vous devez vous assurer que la même value du composant itérer est été préservée lors de la appliquer demande des valeurs phase du formulaire Envoyer la demande. JSF réitérera dessus pour trouver le lien / bouton cliqué et les valeurs d'entrée soumises. Mettre le haricot dans le champ de vision et / ou en vous assurant que vous chargez le modèle de données dans @PostConstruct du grain (et donc pas dans un getter!) Devrait fixer. Voir aussi Comment et quand dois-je charger le modèle de base de données pour h:. dataTable

  5. Si UICommand ou UIInput components sont inclus par une source dynamique comme <ui:include src="#{bean.include}">, alors vous devez vous assurer que la même valeur #{bean.include} est conservée pendant le temps de construction de vue de la forme soumettre la demande. JSF réexécuter pendant la construction de l'arborescence des composants. Mettre le haricot dans le champ de vision et / ou en vous assurant que vous chargez le modèle de données dans @PostConstruct du grain (et donc pas dans un getter!) Devrait fixer. Voir aussi Comment ajax-rafraîchir dynamique inclure le contenu par le menu de navigation? (JSF SPA) .

  6. L'attribut rendered du composant et tous ses parents, et l'attribut test de tout <c:if> parent / <c:when> ne doivent pas évaluer à false au cours de la demande appliquer les valeurs phase du formulaire soumettre la demande. JSF revérifier dans le cadre de la protection contre trafiqués / demandes piraté. Le stockage des variables responsables de la condition dans un grain de @ViewScoped ou en vous assurant que vous preinitializing correctement la condition @PostConstruct d'un grain de @RequestScoped devrait corriger. De même pour l'attribut disabled du composant, qui ne devrait pas évaluer à true appliquer pendant la phase de valeurs de demande. Voir aussi l'action JSF CommandButton pas invoqué et formulaire présenter dans certaines conditions composant rendu n'est pas traitée .

  7. L'attribut onclick du composant UICommand et l'attribut onsubmit du composant UIForm ne doivent pas retourner false ou provoquer une erreur JavaScript. Il devrait y avoir en cas de <h:commandLink> ou <f:ajax> également aucune erreur de JS visible dans la console de JS du navigateur. googler Habituellement, le message d'erreur exact déjà vous donner la réponse. Voir aussi Ajout jQuery pour PrimeFaces résultats dans TypeErrors non interceptées .

  8. Si vous utilisez Ajax via JSF 2.x <f:ajax> ou par exemple PrimeFaces <p:commandXxx>, assurez-vous que vous avez un <h:head> dans le modèle de maître au lieu du <head>. Dans le cas contraire JSF ne sera pas en mesure d'auto-inclure les fichiers JavaScript nécessaires qui contient les fonctions Ajax. Cela entraînerait une erreur JavaScript comme « mojarra n'est pas défini » ou « PrimeFaces n'est pas défini » dans la console du navigateur JS. Voir aussi h: commandLink ActionListener n'est pas invoqué lorsque utilisé avec f: Ajax et ui:. répéter

  9. Si vous utilisez Ajax, et les valeurs soumises finissent par être null, assurez-vous que les composants de UIInput et UICommand d'intérêt sont couverts par la <f:ajax execute> ou par exemple <p:commandXxx process>, sinon ils ne seront pas exécutées / traitées. Voir aussi pas mises à jour modèle lors de l'ajout à et La compréhension des processus PrimeFaces / mise à jour et JSF f: Ajax exécuter / attributs rendent

  10. .
  11. Si les valeurs soumises finissent toujours par être null, et vous utilisez CDI pour gérer les haricots, assurez-vous que you importer l'annotation portée de l'emballage correct, sinon CDI par défaut @Dependent qui reconstitue efficacement le haricot sur chaque seule évaluation de l'expression EL. Voir aussi @SessionScoped desserre haricot portée et recréé tout le temps, les champs deviennent nuls et Quelle est la valeur par défaut géré Scope Bean dans une application JSF 2?

  12. Si un parent du <h:form> avec le bouton UICommand est préalablement été rendue / mise à jour par une demande ajax provenant d'une autre forme dans la même page, la première action échouera toujours dans JSF 2.2 ou plus. Les deuxième et les actions subséquentes travailleront. Ceci est dû à un bogue dans la gestion de l'Etat vue qui est signalé comme problème de spécification JSF 790 et fixé actuellement dans JSF 2.3. Pour les versions plus anciennes JSF, vous devez spécifier explicitement l'ID du <h:form> dans le render du <f:ajax>. Voir aussi h: commandButton / h: commandLink ne fonctionne pas sur le premier clic, ne fonctionne que sur le deuxième clic .

  13. Si le <h:form> a enctype="multipart/form-data" fixé pour soutenir le téléchargement de fichiers, vous devez vous assurer que vous utilisez au moins JSF 2.2, ou que le filtre de servlet qui est responsable de l'analyse syntaxique multipart / form-data demande est correctement configuré, sinon le FacesServlet finira par obtenir aucun paramètre de demande du tout et donc ne pas être en mesure d'appliquer les valeurs de demande. Comment configurer un tel filtre dépend du composant de téléchargement de fichier utilisé. Pour Tomahawk <t:inputFileUpload>, vérifier cette réponse et PrimeFaces <p:fileUpload>, vérifier < a href = "https://stackoverflow.com/questions/8875818/how-to-use-primefaces-pfileupload-listener-method-is-never-invoked/8880083#8880083"> cette réponse . Ou, si vous téléchargez en fait pas un fichier du tout, puis retirez l'attribut tout à fait.

  14. Assurez-vous que l'argument ActionEvent de actionListener est un javax.faces.event.ActionEvent et donc pas java.awt.event.ActionEvent, qui est ce que la plupart des IDEs suggèrent que 1ère option de saisie semi-automatique. Avoir aucun argument est erroné et si vous utilisez actionListener="#{bean.method}". Si vous ne voulez pas un argument dans votre méthode, utilisez actionListener="#{bean.method()}". Ou peut-être vous voulez utiliser action au lieu de actionListener. Voir aussi Les différences entre l'action et actionListener .

  15. Assurez-vous qu'aucun PhaseListener ou tout EventListener dans la chaîne demande-réponse a changé le cycle de vie JSF pour passer la phase d'action Invoke par exemple en appelant FacesContext#renderResponse() ou FacesContext#responseComplete().

  16. Assurez-vous qu'aucun Filter ou Servlet dans la même chaîne demande-réponse a bloqué la demande du fo FacesServlet en quelque sorte.

  17. Si vous utilisez un PrimeFaces <p:dialog> ou <p:overlayPanel>, alors assurez-vous qu'ils ont leur propre <h:form>. Parce que, ces composants sont par défaut par JavaScript déplacé à la fin de HTML <body>. Donc, s'ils étaient assis à l'origine dans un <form>, alors ils maintenant pas rester plus dans un <form>. Voir aussi p: action commandbutton ne fonctionne pas à l'intérieur p: dialogue

  18. Bug dans le cadre. Par exemple, RichFaces a une "erreur de conversion " lors de l'utilisation d'un élément d'interface utilisateur de rich:calendar avec un defaultLabel attribuer (ou, dans certains cas, un sous-élément de rich:placeholder). Ce bogue empêche la méthode de haricot d'être invoqué lorsque aucune valeur est définie pour la date du calendrier. Tracing bugs cadre peut être accompli en commençant par un exemple de travail simple et la construction de la dernière page jusqu'à la découverte du bug.

conseils de débogage

Dans le cas où vous avez encore stucks, il est temps de débogage. Du côté client, appuyez sur F12 pour ouvrir dans webbrowser le jeu d'outils de développeur web. Cliquez sur le Console onglet afin voir le conosle JavaScript. Il doit être exempt de toute erreur JavaScript. Ci-dessous un exemple d'écran est de Chrome qui montre le cas de la présentation d'une touche activée de <f:ajax> sans avoir déclaré <h:head> (comme décrit au point 7 ci-dessus).

 console js

Cliquez sur le Réseau pour voir le moniteur de trafic HTTP. Soumettre le formulaire et vérifier si les en-têtes de demande et sous forme de données et le corps de réponse sont selon les attentes. Ci-dessous capture d'écran est un exemple de Chrome qui démontre un succès ajax présenter d'une forme simple avec un seul <h:inputText> et un seul <h:commandButton> avec <f:ajax execute="@form" render="@form">.

 moniteur de réseau

(avertissement: lorsque vous postez des captures d'écran de têtes de requête HTTP comme ci-dessus à partir d'un environnement de production, alors assurez-vous démener / obscurcir les cookies de session dans la capture d'écran pour éviter les attaques de piratage de session!)

Du côté du serveur, assurez-vous que le serveur est démarré en mode débogage. Mettez un point d'arrêt de débogage dans une méthode de la composante JSF d'intérêt que vous attendez d'être appelé au cours du traitement du formulaire soumis. Par exemple. en cas de composant UICommand, ce serait UICommand#queueEvent() et dans le cas de la composante UIInput, ce serait UIInput#validate() . étape seulement à travers l'exécution du code et vérifier si le débit et les variables sont selon les attentes. Ci-dessous un exemple d'écran à partir du débogueur d'Eclipse.

 serveur de débogage

Autres conseils

Si votre h:commandLink est dans un h:dataTable il y a une autre raison pour laquelle le h:commandLink ne fonctionne pas:

Le sous-jacent de données source qui est liée à la h:dataTable doit également être disponible dans la deuxième JSF-Cycle de vie qui est déclenché lorsque le lien est cliqué.

Donc, si le sous-jacent des données source demande scope, la h:commandLink ne fonctionne pas!

Alors que ma réponse n'est pas 100% applicable, mais la plupart des moteurs de recherche trouvent cela comme le premier coup, j'ai décidé de l'afficher nontheless:

Si vous utilisez PrimeFaces (ou une API similaire) ou de p:commandButton p:commandLink, les chances sont que vous avez oublié d'ajouter explicitement process="@this" à vos composants de commande.

Comme le PrimeFaces Guide de l'utilisateur dispose à l'article 3.18, les valeurs par défaut pour process et update sont à la fois @form, qui oppose à peu près les paramètres par défaut que vous pourriez attendre de f:ajax JSF ordinaire ou RichFaces, qui sont execute="@this" et render="@none" respectivement.

Juste m'a pris un temps très longue pour découvrir. (... et je pense qu'il est plutôt unclever d'utiliser les valeurs par défaut qui sont différents de JSF!)

Je voudrais mentionner une chose qui concerne la p:commandButton de Primefaces!

Lorsque vous utilisez un p:commandButton pour l'action qui doit être fait sur le serveur, vous ne pouvez pas utiliser type="button" parce que c'est Boutons qui sont utilisés pour exécuter javascript personnalisés sans provoquer ajax / demande non ajax au serveur.

Pour cela, vous pouvez dispensez l'attribut type (valeur par défaut est "submit") ou vous pouvez utiliser explicitement type="submit".

Espérons que cela aidera quelqu'un!

est resté coincé avec ce problème moi-même et trouvé une autre cause de ce problème. Si vous ne disposez pas de méthodes setter dans votre backing bean pour les propriétés utilisées dans votre * xhtml, l'action est tout simplement pas invoqué.

J'ai récemment rencontré un problème avec un UICommand pas invoquer dans une application JSF 1.2 en utilisant des composants Faces IBM Extended.

J'ai eu un bouton de commande sur une ligne d'une table de données (la version étendue, donc <hx:datatable>) et le UICommand ne tire pas de certaines lignes de la table (les lignes qui ne serait pas le feu étaient les rangs plus que l'affichage de la ligne par défaut taille).

J'ai eu une composante déroulante pour sélectionner le nombre de lignes à afficher. La valeur soutenant ce domaine était RequestScope. Les données qui soutiennent la table elle-même était dans une sorte de ViewScope (en réalité, temporairement SessionScope).

Si l'affichage de la ligne a été augmentée par la commande dont la valeur a également été lié à l'attribut rows du datatable, aucune des lignes affichées à la suite de ce changement pourrait tirer le UICommand lorsque vous cliquez dessus.

placer cet attribut dans la même portée que les données de la table elle-même fixée le problème.

Je pense que cela est fait allusion dans BalusC 4 ci-dessus, mais non seulement la valeur de la table doivent être View ou session scope mais aussi l'attribut contrôlant le nombre de lignes à afficher sur cette table.

J'ai eu ce problème aussi bien et que vraiment commencé à se concentrer sur la cause racine après l'ouverture de la console Web du navigateur. Jusque-là, je ne pouvais pas obtenir un message d'erreur (même avec <p:messages>). La console Web a montré un code d'état HTTP 405 en revenant de la <h:commandButton type="submit" action="#{myBean.submit}">.

Dans mon cas, j'ai un mélange de vanille HttpServlet fournisse, l'authentification OAuth via facelets Auth0 et JSF et les haricots portant mon point de vue de l'application et la logique métier.

Une fois que je refactorisé mon web.xml, et enlevé un servlet middle-man, il a ensuite "magie" a travaillé.

En bout de ligne, le problème était que le milieu-homme servlet utilisait RequestDispatcher.forward (...) pour rediriger de l'environnement HttpServlet à l'environnement JSF alors que le servlet appelé avant il a été réorientent avec HttpServletResponse.sendRedirect (...).

En fait, en utilisant sendRedirect () a permis au JSF "conteneur" de prendre le contrôle alors que RequestDispatcher.forward () est évidemment pas.

Ce que je ne sais pas pourquoi le Facelet a pu accéder aux propriétés de haricots mais n'a pas pu les mettre, et cela crie clairement faire disparaître avec le mélange de servlets et JSF, mais j'espère que cela aide quelqu'un d'éviter de nombreuses heures de tête-à-table-claquement.

J'ai eu beaucoup de plaisir débogage d'un problème où l'action d'un <h:commandLink> dans richfaces datatable a refusé de tirer. Le tableau utilisé pour travailler à un moment donné mais arrêté sans raison apparente. Je remué ciel et terre, pour savoir que mon rich:datatable utilisait la mauvaise rowKeyConverter qui est revenu que richfaces heureusement nulls utilisés en tant que touches de ligne. Cela a empêché mon action <h:commandLink> de se faire appeler.

Une autre possibilité: si le symptôme est que le premier appel fonctionne, mais les suivantes ne sont pas, vous pouvez utiliser 3.x PrimeFaces avec JSF 2.2, comme indiqué ici: Non ViewState est envoyé .

Je fixe mon problème en plaçant le:

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

Pour résoudre;

<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>
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top