Saltar al contenido

commandButton / commandLink / ajax action / listener método no invocado o valor de entrada no establecido / actualizado

Solución:

Introducción

Siempre que un UICommand componente (, , etc.) no puede invocar el método de acción asociado, o un UIInput componente (, , etc.) no procesa los valores enviados y / o actualiza los valores del modelo, y no ve ninguna excepción y / o advertencia que se puedan buscar en Google en el registro del servidor, tampoco cuando configura un controlador de excepciones ajax según el manejo de excepciones en JSF solicitudes ajax, ni cuando establece el siguiente parámetro de contexto en web.xml,


    javax.faces.PROJECT_STAGE
    Development

y tampoco ve ningún error y / o advertencia que se pueda buscar en Google 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 el Consola pestaña), luego trabaje con la siguiente lista de posibles causas.

Posibles Causas

  1. UICommand y UIInput Los componentes deben colocarse dentro de un UIForm componente, p. ej. (y, por lo tanto, no HTML simple

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

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

  3. No UIInput Debería haber ocurrido un error de validación / conversión de valor. Puedes usar para mostrar cualquier mensaje que no se muestre por ninguna entrada específica componentes. No olvide incluir el id de en el , si corresponde, para que también se actualice en las solicitudes ajax. Consulte también h: messages no muestra mensajes cuando se presiona p: commandButton.

  4. Si UICommand o UIInput Los componentes se colocan dentro de un componente iterativo como , , etc., debe asegurarse de que exactamente lo mismo value del componente iterativo se conserva durante la fase de aplicación de valores de solicitud de la solicitud de envío de formulario. JSF lo reiterará para encontrar el enlace / botón en el que se hizo clic y los valores de entrada enviados. Poner el bean en el alcance 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 UICommand o UIInput Los componentes están incluidos por una fuente dinámica como , entonces debe asegurarse de que exactamente lo mismo #bean.include El valor se conserva durante el tiempo de creación de la vista de la solicitud de envío del formulario. JSF lo volverá a ejecutar durante la construcción del árbol de componentes. Poner el bean en el alcance 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 ajax-refresh Dynamic Incluir contenido por menú de navegación? (JSF SPA).

  6. los rendered attribute del componente y todos sus padres y el test attribute de cualquier padre / no debería evaluar a false durante la fase de aplicación de valores de solicitud del formulario enviar solicitud. JSF lo volverá a verificar como parte de la protección contra solicitudes manipuladas / pirateadas. Almacenar las variables responsables de la condición en un @ViewScoped bean o asegurándose de que está preinicializando correctamente la condición en @PostConstruct de un @RequestScoped bean debería arreglarlo. Lo mismo se aplica a la disabled y readonly attributes del componente, que no debe evaluarse true durante la fase de aplicación de valores de solicitud. Consulte también la acción JSF CommandButton no invocada, el envío de formulario en el componente renderizado condicionalmente no se procesa, h: commandButton no funciona una vez que lo envuelvo en un y Forzar JSF para procesar, validar y actualizar componentes de entrada de solo lectura / deshabilitados de todos modos

  7. los onclick attribute de El UICommand componente y el onsubmit attribute de El UIForm el componente no debe regresar false o provocar un error de JavaScript. Debería en caso de o Tampoco habrá errores JS visibles en la consola JS del navegador. Por lo general, buscar en Google el mensaje de error exacto ya te dará la respuesta. Consulte también Agregar / cargar jQuery manualmente con PrimeFaces resultados en Uncaught TypeErrors.

  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 la . De lo contrario, JSF no podrá incluir automáticamente los archivos JavaScript necesarios que contienen las funciones 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. Consulte también h: commandLink actionlistener no se invoca cuando se usa con f: ajax y ui: repeat.

  9. Si está utilizando Ajax y los valores enviados terminan siendo null, luego asegúrese de que el UIInput y UICommand componentes de interés están cubiertos por la o por ejemplo , de lo contrario no se ejecutarán / procesarán. Consulte también Los valores del formulario enviado no se actualizan en el modelo al agregar para y Comprensión del proceso / actualización de PrimeFaces y JSF f: ajax execute / render attributes.

  10. Si los valores enviados aún terminan siendo null, y está utilizando CDI para administrar beans, luego asegúrese de importar la anotación de alcance del paquete correcto; de lo contrario, CDI se establecerá de forma predeterminada en @Dependent que recrea efectivamente el bean en cada evaluación de la expresión EL. Véase también @SessionScoped bean pierde alcance y se vuelve a crear todo el tiempo, los campos se vuelven null y ¿Cuál es el ámbito de bean administrado predeterminado en una aplicación JSF 2?

  11. Si un padre del con el UICommand El botón se ha renderizado / actualizado de antemano mediante una solicitud ajax procedente de otro formulario en la misma página, entonces la primera acción siempre fallará en JSF 2.2 o anterior. La segunda y las siguientes acciones funcionarán. Esto se debe a un error en el manejo del estado de la vista que se informa como problema de especificación JSF 790 y actualmente se corrigió en JSF 2.3. Para versiones anteriores de JSF, debe especificar explícitamente el ID del en el render de El . Consulte también h: commandButton / h: commandLink no funciona en el primer clic, funciona solo en el segundo clic.

  12. Si el tiene enctype="multipart/form-data" configurado para admitir la carga de archivos, debe asegurarse de que está utilizando al menos JSF 2.2, o que el filtro de servlet que es responsable de analizar las solicitudes de datos de formulario / multiparte está configurado correctamente; de ​​lo contrario, el FacesServlet terminará sin obtener ningún parámetro de solicitud y, por lo tanto, no podrá aplicar los valores de solicitud. La forma de configurar dicho filtro depende del componente de carga de archivos que se utilice. Para Tomahawk , verifique esta respuesta y para PrimeFaces , compruebe esta respuesta. O, si en realidad no está cargando un archivo, elimine el attribute en total.

  13. Asegúrese de que el ActionEvent argumento de actionListener es un javax.faces.event.ActionEvent y por lo tanto no java.awt.event.ActionEvent, que es lo que la mayoría de los IDE sugieren como primera opción de autocompletar. No tener ningún argumento también está mal si usa actionListener="#bean.method". Si no quiere un argumento en su método, use actionListener="#bean.method()". O tal vez quieras usar action en lugar de actionListener. Consulte también Diferencias entre action y actionListener.

  14. Asegúrate de que no PhaseListener o cualquier EventListener en la cadena de solicitud-respuesta ha cambiado el ciclo de vida de JSF para omitir la fase de acción de invocación, por ejemplo, llamando FacesContext#renderResponse() o FacesContext#responseComplete().

  15. Asegúrate de que no Filter o Servlet en la misma cadena de solicitud-respuesta ha bloqueado la solicitud de FacesServlet de alguna manera. Por ejemplo, filtros de inicio de sesión / seguridad como Spring Security. Particularmente en las solicitudes ajax que, de forma predeterminada, terminarían sin ningún comentario de la interfaz de usuario. Consulte también el manejo de solicitudes Spring Security 4 y PrimeFaces 5 AJAX.

  16. Si está utilizando PrimeFaces o un , luego asegúrese de que tengan su propio . Porque, de forma predeterminada, JavaScript reubica estos componentes al final de HTML . Entonces, si originalmente estuvieran sentados dentro de un

    , entonces ya no se sentarían más en un

    . Consulte también p: la acción del botón de comando no funciona dentro de p: dialog

  17. Error en el marco. Por ejemplo, RichFaces tiene un “error de conversión” cuando se utiliza un rich:calendar Elemento de interfaz de usuario con un defaultLabel attribute (o, en algunos casos, un rich:placeholder subelemento). Este error evita que se invoque el método bean cuando no se establece ningún valor para la fecha del calendario. El seguimiento de los errores del marco se puede lograr comenzando con un ejemplo de trabajo simple y construyendo la página de nuevo hasta que se descubra el error.

Sugerencias de depuración

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

consola js

Haga clic en el La red pestaña para ver el monitor de tráfico HTTP. Envíe el formulario e investigue si los encabezados de la solicitud y los datos del formulario y el cuerpo de la respuesta cumplen con las expectativas. La siguiente captura de pantalla es un ejemplo de Chrome que demuestra un envío ajax exitoso de un formulario simple con un solo y un solo con .

monitor de red

(advertencia: cuando publique capturas de pantalla de encabezados de solicitud HTTP como el anterior desde un entorno de producción, asegúrese de codificar / ofuscar cualquier cookie 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. Ponga un punto de interrupción de depuración en un método del componente JSF de interés que espera que se llame durante el procesamiento del envío del formulario. Por ejemplo, en caso de UICommand componente, que sería UICommand#queueEvent() y en caso de UIInput componente, que sería UIInput#validate(). Simplemente recorra la ejecución del código e inspeccione si el flujo y las variables cumplen con las expectativas. La siguiente captura de pantalla es un ejemplo del depurador de Eclipse.

servidor de depuración

Si tu h:commandLink está dentro de un h:dataTable hay otra razón por la que el h:commandLink podría no funcionar:

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

Entonces, si la fuente de datos subyacente tiene un alcance de solicitud, el h:commandLink ¡No funciona!

Si bien mi respuesta no es 100% aplicable, pero la mayoría de los motores de búsqueda encuentran esto como el primer resultado, decidí publicarlo de todos modos:

Si estas usando 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 establece la Guía del usuario de PrimeFaces en la sección 3.18, los valores predeterminados para process y update son ambos @form, que prácticamente se opone a los valores predeterminados que podría esperar de JSF simple f:ajax o RichFaces, que son execute="@this" y render="@none" respectivamente.

Me tomó mucho tiempo averiguarlo. (… ¡y creo que es bastante poco inteligente usar valores predeterminados que son diferentes de JSF!)

Comentarios y puntuaciones del tutorial

Recuerda que puedes mostrar este artículo si te fue de ayuda.

¡Haz clic para puntuar esta entrada!
(Votos: 2 Promedio: 4.5)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *