commandButton / commandLink / ajax action / listener method no invocado o input value not set / updated

Algunas veces, cuando se usa , o , la action , el actionListener o el método de listener asociados con la etiqueta simplemente no se invocan. O bien, las propiedades de los UIInput no se actualizan con los valores de UIInput enviados.

¿Cuáles son las posibles causas y soluciones para esto?

Introducción

Cuando un componente de UICommand ( , , etc.) no puede invocar el método de acción asociado, o un componente de UIInput ( , , etc.) no procesa el envió valores y / o actualizó los valores del modelo, y no está viendo ninguna excepción y / o advertencia en el registro del servidor, tampoco cuando configura un manejador de excepciones ajax según el manejo de excepciones en solicitudes JSF ajax , ni cuando configura debajo del parámetro de contexto en web.xml ,

  javax.faces.PROJECT_STAGE Development  

y tampoco está viendo ningún error y / o advertencia en la consola de JavaScript del navegador (presione F12 en Chrome / Firefox23 + / IE9 + para abrir el conjunto de herramientas del desarrollador web y luego abra la pestaña Consola ), luego revise la lista de posibles causas a continuación.

Posibles causas

  1. UICommand componentes UICommand y UIInput deben colocarse dentro de un componente UIForm , por ejemplo, (y, por lo tanto, no es HTML

    ), de lo contrario, no se puede enviar nada al servidor. UICommand componentes de UICommand tampoco deben tener el atributo type="button" , de lo contrario será un botón UICommand que solo es útil para hacer clic en JavaScript. Consulte también Cómo enviar valores de entrada de formulario e invocar un método en beans JSF y no inicia una devolución de datos .

  2. No puede anidar múltiples componentes de UIForm entre sí. Esto es ilegal en HTML. El comportamiento del navegador no está especificado. ¡Cuidado con los archivos de inclusión! Puede usar los componentes de UIForm en paralelo, pero no se procesarán entre sí durante el envío. También debes tener cuidado con el antipatrón “God Form”; asegúrese de no procesar / validar involuntariamente todas las demás entradas (invisibles) en la misma forma (por ejemplo, tener un cuadro de diálogo oculto con las entradas necesarias en la misma forma). Consulte también Cómo utilizar en la página JSF? ¿Forma única? Múltiples formas? Formas anidadas? .

  3. No debe haber ocurrido ningún UIInput validación / conversión del valor de UIInput . Puede usar para mostrar cualquier mensaje que no se muestre con ningún componente específico de la entrada. No olvide incluir el id de en el , si lo hay, para que también se actualice en solicitudes ajax. Ver también h: messages no muestra mensajes cuando se presiona p: commandButton .

  4. Si los componentes UICommand o UIInput se colocan dentro de un componente como , , etc., debe asegurarse de que se conserve exactamente el mismo value del componente iterativo durante la fase de solicitud de valores de solicitud de la solicitud de envío del formulario. JSF reiterará sobre él para encontrar el enlace / botón en el que se hizo clic y los valores de entrada enviados. Poner el bean en el scope de la vista y / o asegurarse de cargar el modelo de datos en @PostConstruct del bean (y por lo tanto no en un método getter) debería arreglarlo. Consulte también Cómo y cuándo debo cargar el modelo de la base de datos para h: dataTable .

  5. Si los componentes UICommand o UIInput son incluidos por una fuente dinámica como , entonces debe asegurarse de que se conserve exactamente el mismo valor #{bean.include} durante la vista tiempo de comstackción de la solicitud de envío del formulario. JSF lo ejecutará de nuevo durante la creación del árbol de componentes. Poner el bean en el scope de la vista y / o asegurarse de cargar el modelo de datos en @PostConstruct del bean (y por lo tanto no en un método getter) debería arreglarlo. Consulte también How to ajax-refresh dynamic include content by navigation menu? (JSF SPA) .

  6. El atributo rendered del componente y todos sus elementos primarios y el atributo de test de cualquier elemento primario / no debe evaluarse como false durante la fase aplicar valores de solicitud de la solicitud de envío de formulario. JSF volverá a verificarlo como parte de la protección contra las solicitudes manipuladas / pirateadas. El almacenamiento de las variables responsables de la condición en un bean @ViewScoped o asegurarse de que está preiniciando correctamente la condición en @PostConstruct de un bean @RequestScoped debe solucionarlo. Lo mismo se aplica al atributo disabled del componente, que no debe evaluarse como true durante la fase de solicitud de valores de solicitud. Consulte también Acción JSF CommandButton no invocada y Formulario enviado en componente condicionalmente procesado no se procesa .

  7. El atributo onclick del componente UICommand y el atributo UIForm componente UIForm no debe devolver false o causar un error de JavaScript. En caso de o tampoco debería haber errores JS visibles en la consola JS del navegador. Por lo general, googlear el mensaje de error exacto ya le dará la respuesta. Consulte también Agregar resultados de jQuery a PrimeFaces en Unkeught TypeError en cualquier lugar .

  8. Si está utilizando Ajax a través de JSF 2.x o, por ejemplo, PrimeFaces , asegúrese de tener un en la plantilla maestra en lugar de . De lo contrario, JSF no podrá incluir automáticamente los archivos JavaScript necesarios que contienen las funciones de Ajax. Esto daría como resultado un error de JavaScript como “mojarra no está definido” o “PrimeFaces no está definido” en la consola JS del navegador. Ver también h: commandListener actionLink no se invoca cuando se usa con f: ajax y ui: repeat .

  9. Si está utilizando Ajax, asegúrese de que los componentes UIInput y UICommand de interés están cubiertos por o, por ejemplo, , de lo contrario no se ejecutarán / procesarán. Consulte también Valores de formularios enviados no actualizados en el modelo al agregar a y Understanding PrimeFaces process / update y JSF f: ajax execute / render attributes .

  10. Si un padre de la con el botón UICommand se ha renderizado / actualizado previamente mediante una solicitud ajax proveniente de otro formulario en la misma página, entonces la primera acción siempre fallará. La segunda y posteriores acciones funcionarán. Esto se debe a un error en el manejo del estado de la vista que se informa como el problema de especificación JSF 790 y está progtwigdo actualmente para ser corregido en JSF 2.3. Para versiones anteriores de JSF, debe especificar explícitamente la ID de la en el render de la . Ver también h: commandButton / h: commandLink no funciona con el primer clic, solo funciona con un segundo clic .

  11. Si tiene enctype="multipart/form-data" establecido para permitir la carga de archivos, entonces debe asegurarse de estar utilizando al menos JSF 2.2, o de que el filtro de servlet que es responsable de El análisis de las solicitudes multipart / form-data está configurado correctamente; de ​​lo contrario, FacesServlet terminará sin obtener ningún parámetro de solicitud y, por lo tanto, no podrá aplicar los valores de solicitud. La configuración de dicho filtro depende del componente de carga de archivo que se esté utilizando. Para Tomahawk , verifique esta respuesta y para PrimeFaces , verifique esta respuesta . O bien, si en realidad no está cargando ningún archivo, elimine el atributo por completo.

  12. Asegúrese de que el argumento ActionEvent de actionListener sea javax.faces.event.ActionEvent y, por lo tanto, no java.awt.event.ActionEvent , que es lo que la mayoría de los IDEs sugieren como la primera opción de autocompletar. No tener ningún argumento también es incorrecto si usas actionListener="#{bean.method}" . Si no quiere un argumento en su método, use actionListener="#{bean.method()}" . O quizás realmente quiera usar action lugar de actionListener . Ver también Diferencias entre action y actionListener .

  13. Asegúrese de que ningún PhaseListener o ningún EventListener en la cadena de solicitud-respuesta haya cambiado el ciclo de vida de JSF para omitir la fase de invocación, por ejemplo llamando a FacesContext#renderResponse() o FacesContext#responseComplete() .

  14. Asegúrese de que ningún Filter o Servlet en la misma cadena de solicitud-respuesta haya bloqueado la solicitud de FacesServlet alguna manera.

  15. Error en el marco. Por ejemplo, RichFaces tiene un ” error de conversión ” al usar un elemento de IU rich:calendar con un atributo de defaultLabel (o, en algunos casos, un subelemento de rich:placeholder ). Este error evita que se invoque el método de bean cuando no se establece ningún valor para la fecha del calendario. Los errores del sistema de rastreo pueden lograrse comenzando con un ejemplo de trabajo simple y creando una copia de seguridad de la página hasta que se descubra el error.

  16. Si está utilizando un p:dialog PrimeFaces p:dialog o un p:overlayPanel , asegúrese de que no se encuentra con p: botón de comando La acción no funciona dentro de p: diálogo

Sugerencias de depuración

En caso de que todavía tenga problemas, es hora de depurar. En el lado del cliente, presione F12 en webbrowser para abrir el conjunto de herramientas del desarrollador web. Haga clic en la pestaña Consola para ver el conosle de JavaScript. Debe estar libre de errores de JavaScript. La siguiente captura de pantalla es un ejemplo de Chrome que muestra el caso de enviar un botón habilitado sin tener declarado (como se describe en el punto 7 anterior).

Consola js

Haga clic en la pestaña Red para ver el monitor de tráfico HTTP. Envíe el formulario e investigue si los encabezados de solicitud y los datos de formulario y el cuerpo de respuesta son según las expectativas. La siguiente captura de pantalla es un ejemplo de Chrome que muestra un ajax exitoso de un formulario simple con una sola y una sola con .

monitor de red

(advertencia: cuando publique capturas de pantalla de encabezados de solicitud HTTP como los anteriores de un entorno de producción, asegúrese de codificar / ocultar las cookies de sesión en la captura de pantalla para evitar ataques de secuestro de sesión).

En el lado del servidor, asegúrese de que el servidor se inicie en modo de depuración. Coloque un punto de corte de depuración en un método del componente de interés de JSF que espera que se llame durante el procesamiento del envío del formulario. Por ejemplo, en el caso del componente UICommand , ese sería UICommand#queueEvent() y en el caso del componente UIInput , sería UIInput#validate() . Solo pise la ejecución del código e inspeccione si el flujo y las variables son según las expectativas. La siguiente captura de pantalla es un ejemplo del depurador de Eclipse.

depurar servidor

Si su h:commandLink está dentro de h:dataTable existe otra razón por la cual h: commandLink podría no funcionar:

La fuente de datos subyacente que está vinculada a h:dataTable también debe estar disponible en el segundo JSF-Lifecycle que se activa cuando se hace clic en el enlace.

Entonces, si la fuente de datos subyacente tiene un scope de solicitud, h:commandLink no funciona.

Si bien mi respuesta no es 100% aplicable, pero la mayoría de los motores de búsqueda lo encuentran como el primer golpe, decidí publicarlo sin excepción:

Si está utilizando PrimeFaces (o alguna API similar) p:commandButton o p:commandLink , es probable que haya olvidado agregar explícitamente process="@this" a sus componentes de comando.

Como la Guía del usuario de PrimeFaces establece en la sección 3.18, los valores predeterminados para el process y la update son ambos @form , que se opone bastante a los valores predeterminados que podría esperar de JSF simple f:ajax o RichFaces, que son execute="@this" y render="@none" respectivamente.

Me llevó mucho tiempo averiguarlo. (… y creo que es bastante imprudente utilizar valores predeterminados que son diferentes de JSF!)

Mencionaría una cosa más que concierne al p:commandButton .

Cuando utiliza un p:commandButton para la acción que debe realizarse en el servidor, no puede usar type="button" porque es para los botones Push que se utilizan para ejecutar javascript personalizado sin causar una solicitud ajax / no-ajax al servidor.

Para este propósito, puede dispensar el atributo type (el valor predeterminado es "submit" ) o puede usar explícitamente type="submit" .

¡Espero que esto ayude a alguien!

Recientemente me encontré con un problema con un UICommand que no invoca en una aplicación JSF 1.2 utilizando IBM Extended Faces Components.

Tenía un botón de comando en una fila de una tabla de datos (la versión extendida, por lo que ) y UICommand no se activaría desde ciertas filas de la tabla (las filas que no dispararían serían las filas mayores que la fila predeterminada tamaño de la pantalla).

Tenía un componente desplegable para seleccionar el número de filas para mostrar. El valor que respalda este campo estaba en RequestScope . Los datos que respaldaban la tabla estaban en una especie de ViewScope (en realidad, temporalmente en SessionScope ).

Si la visualización de la fila se aumentó mediante el control cuyo valor también estaba vinculado al atributo de rows la tabla de datos, ninguna de las filas que se muestran como resultado de este cambio podría disparar el UICommand cuando se haga clic.

Colocar este atributo en el mismo ámbito que los datos de la tabla en sí arreglaron el problema.

Creo que esto se menciona en BalusC # 4 anterior, pero no solo el valor de la tabla debe ser Ver o Período de sesión, sino también el atributo que controla el número de filas para mostrar en esa tabla.

Me he quedado atascado con este problema y encontré una causa más para este problema. Si no tiene métodos setter en su bean de respaldo para las propiedades utilizadas en su * .xhtml, entonces la acción simplemente no se invoca.

También tuve este problema y solo realmente comencé a centrarme en la causa raíz después de abrir la consola web del navegador. Hasta ese momento, no pude obtener ningún mensaje de error (incluso con ). La consola web mostró un código de estado HTTP 405 que regresaba del .

En mi caso, tengo una mezcla de vainilla HttpServlet que proporciona autenticación OAuth a través de fajas y frijoles Auth0 y JSF que llevan a cabo las vistas de mi aplicación y la lógica comercial.

Una vez que refactore mi web.xml, y eliminé un middle-man-servlet, funcionó “mágicamente”.

En pocas palabras, el problema era que el middle-man-servlet estaba usando RequestDispatcher.forward (…) para redirigir desde el entorno HttpServlet al entorno JSF, mientras que el servlet al que se llamaba antes estaba redirigiendo con HttpServletResponse.sendRedirect (… .).

Básicamente, el uso de sendRedirect () permitió que el “contenedor” JSF tomara el control, mientras que RequestDispatcher.forward () obviamente no lo era.

Lo que no sé es por qué el facelet pudo acceder a las propiedades del frijol pero no pudo configurarlas, y esto claramente clama por eliminar la mezcla de servlets y JSF, pero espero que esto ayude a alguien a evitar muchas horas de trabajo. to-table-banging.

Me muchísimo depurando un problema donde la acción de un en richfaces datatable negó a disparar. La mesa solía funcionar en algún punto pero se detenía sin ningún motivo aparente. No dejé piedra sin remover, solo para descubrir que mi rich:datatable usaba el rowKeyConverter incorrecto que devolvía los nulos que las rich:datatable usaban felizmente como claves de fila. Esto impidió que mi acción se llamara.

Una posibilidad más: si el síntoma es que la primera invocación funciona, pero las siguientes no, puede utilizar PrimeFaces 3.x con JSF 2.2, como se detalla aquí: No se envía ViewState .