CommandButton/commandLink/ajax acción/método de escucha no invocado o valor de entrada no establecido/actualizado

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

Pregunta

A veces, al usar <h:commandLink>, <h:commandButton> o <f:ajax>, el action, actionListener o listener El método asociado con la etiqueta simplemente no se invoca.O bien, las propiedades del frijol no se actualizan con el envío. UIInput valores.

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

¿Fue útil?

Solución

Introducción

Siempre que un UICommand componente (<h:commandXxx>, <p:commandXxx>, etc) no puede invocar el método de acción asociado, o un UIInput componente (<h:inputXxx>, <p:inputXxxx>, etc.) no puede procesar los valores enviados y/o actualizar los valores del modelo, y no ve ninguna excepción y/o advertencia que se pueda buscar en Google en el registro del servidor, tampoco cuando configura un controlador de excepciones ajax según Manejo de excepciones en solicitudes JSF ajax, ni cuando establece el parámetro de contexto debajo en web.xml,

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

y tampoco ve ningún error y/o advertencia que se pueda buscar en Google en la consola JavaScript del navegador (presione F12 en Chrome/Firefox23+/IE9+ para abrir el conjunto de herramientas para desarrolladores web y luego abra el Consola pestaña), luego revise la siguiente lista de posibles causas.

Posibles Causas

  1. UICommand y UIInput Los componentes deben colocarse dentro de un UIForm componente, p.e. <h:form> (y por lo tanto no HTML simple <form>), de lo contrario no se podrá enviar nada al servidor. UICommand Los componentes tampoco deben tener type="button" atributo, de lo contrario será un botón muerto que sólo es útil para JavaScript onclick.Ver también Cómo enviar valores de entrada de formulario e invocar un método en el bean JSF y <h:commandButton> no inicia una devolución de datos.

  2. No puedes anidar varios UIForm componentes entre sí.Esto es ilegal en HTML.El comportamiento del navegador no está especificado.¡Cuidado con los archivos incluidos!Puedes usar UIForm componentes 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 (p. ej.tener un cuadro de diálogo oculto con las entradas requeridas en el mismo formulario).Ver también ¿Cómo utilizar <h:form> en la página JSF?¿Forma única?¿Múltiples formas?¿Formularios anidados?.

  3. No UIInput Debería haberse producido un error de validación/conversión de valor.Puedes usar <h:messages> para mostrar cualquier mensaje que no se muestre mediante ninguna entrada específica <h:message> componentes.No olvides incluir el id de <h:messages> en el <f:ajax render>, si lo hay, para que también se actualice en las solicitudes de ajax.Ver 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 <h:dataTable>, <ui:repeat>, etc, entonces debes asegurarte 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 del 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 solucionarlo.Ver también ¿Cómo y cuándo debo cargar el modelo desde la base de datos para h:dataTable?.

  5. Si UICommand o UIInput Los componentes son incluidos por una fuente dinámica como <ui:include src="#{bean.include}">, entonces debes asegurarte 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 solucionarlo.Ver también ¿Cómo actualizar ajax de forma dinámica e incluir contenido mediante el menú de navegación?(JSF SPA).

  6. El rendered atributo del componente y todos sus padres y el test atributo de cualquier padre <c:if>/<c:when> no debe evaluar a false durante la fase de aplicación de valores de solicitud del formulario de envío de solicitud.JSF lo volverá a verificar como parte de la protección contra solicitudes manipuladas o 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 atributo del componente, que no debe evaluarse como true durante la fase de aplicación de valores de solicitud.Ver también La acción JSF CommandButton no se invoca y El envío del formulario en el componente renderizado condicionalmente no se procesa.

  7. El onclick atributo de la UICommand componente y el onsubmit atributo de la UIForm El componente no debe regresar. false o causar un error de JavaScript.Debería haber en caso de <h:commandLink> o <f:ajax> Tampoco habrá errores JS visibles en la consola JS del navegador.Por lo general, buscar en Google el mensaje de error exacto ya le dará la respuesta.Ver también Agregar jQuery a PrimeFaces genera errores de tipo no detectados.

  8. Si estás usando Ajax a través de JSF 2.x <f:ajax> o por ej.caras principales <p:commandXxx>, asegúrese de tener un <h:head> en la plantilla maestra en lugar de la <head>.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: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 Los componentes de interés están cubiertos por el <f:ajax execute> o por ej. <p:commandXxx process>, de lo contrario no serán ejecutados/procesados.Ver también Los valores del formulario enviado no se actualizan en el modelo al agregar <f:ajax> a <h:commandButton> y Comprender el proceso/actualización de PrimeFaces y los atributos de ejecución/renderización JSF f:ajax.

  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 usará de manera predeterminada @Dependent que recrea efectivamente el bean en cada evaluación de la expresión EL.Ver también El bean @SessionScoped pierde alcance y se recrea todo el tiempo, los campos se vuelven nulos y ¿Cuál es el alcance del Bean administrado predeterminado en una aplicación JSF 2?

  11. Si un padre del <h:form> con el UICommand El botón 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á en JSF 2.2 o anterior.La segunda acción y las siguientes funcionarán.Esto se debe a un error en el manejo del estado de vista que se informa como Problema de especificación JSF 790 y actualmente arreglado en JSF 2.3.Para versiones anteriores de JSF, debe especificar explícitamente el ID del <h:form> en el render del <f:ajax>.Ver también h:commandButton/h:commandLink no funciona con el primer clic, solo funciona con el segundo clic.

  12. Si el <h:form> tiene enctype="multipart/form-data" configurado para admitir la carga de archivos, entonces debe asegurarse de que está utilizando al menos JSF 2.2, o que el filtro de servlet responsable de analizar las solicitudes de datos de formularios/multipartes 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 <t:inputFileUpload>, controlar esta respuesta y para PrimeFaces <p:fileUpload>, controlar esta respuesta.O, si en realidad no estás cargando ningún archivo, elimina el atributo por completo.

  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 argumentos también es incorrecto si usas actionListener="#{bean.method}".Si no desea un argumento en su método, utilice actionListener="#{bean.method()}".O tal vez realmente quieras usar action en lugar de actionListener.Ver también Diferencias entre acción 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 invocación de acción, por ejemplo llamando FacesContext#renderResponse() o FacesContext#responseComplete().

  15. Asegúrate de que no Filter o Servlet en la misma cadena solicitud-respuesta ha bloqueado la solicitud del FacesServlet de alguna manera.

  16. Si está utilizando PrimeFaces <p:dialog> o un <p:overlayPanel>, luego asegúrese de que tengan su propio <h:form>.Porque JavaScript reubica estos componentes de forma predeterminada al final de HTML <body>.Entonces, si originalmente estuvieran sentados dentro de un <form>, entonces ya no se sentarían en un <form>.Ver también p: la acción del botón de comando no funciona dentro de p: diálogo

  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 atributo (o, en algunos casos, un rich:placeholder subelemento).Este error impide que se invoque el método bean cuando no se establece ningún valor para la fecha del calendario.El seguimiento de errores del marco se puede lograr comenzando con un ejemplo funcional simple y construyendo una copia de seguridad de la página hasta que se descubra el error.

Sugerencias de depuración

En caso de que todavía te quedes 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 así que consulte la consola 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 <f:ajax> botón habilitado sin tener <h:head> declarado (como se describe en el punto 7 anterior).

js console

Haga clic en el Red para ver el monitor de tráfico HTTP.Envíe el formulario e investigue si los encabezados de la solicitud, 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 <h:inputText> y un solo <h:commandButton> con <f:ajax execute="@form" render="@form">.

network monitor

(advertencia:cuando publica capturas de pantalla de encabezados de solicitud HTTP como se muestra arriba 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.Coloque 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.P.ej.en caso de UICommand componente, eso sería UICommand#queueEvent() y en caso de UIInput componente, eso sería UIInput#validate().Simplemente revise 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.

debug server

Otros consejos

Si su h:commandLink está dentro de un h:dataTable hay otra razón por la h:commandLink puede que no funcione:

Los datos de código subyacente que está unido a la h:dataTable también debe estar disponible en el segundo JSF-ciclo de vida que se desencadena cuando se hace clic en el enlace.

Así que si los datos de código subyacente es un ámbito de petición, el h:commandLink no funciona!

Mientras que mi respuesta no es 100% aplicable, pero la mayoría de los motores de búsqueda encontrar esto como el primer éxito, decidí publicarlo nontheless:

Si está utilizando PrimeFaces (o algún API similar) p:commandButton o p:commandLink, lo más probable es que usted ha olvidado de añadir explícitamente process="@this" a los componentes de su comando.

Guía de la PrimeFaces del usuario declara en la sección 3.18, los valores por defecto para process y update son tanto @form, que se opone más o menos los valores por defecto que puede esperar de f:ajax JSF simple o RichFaces, que son execute="@this" y render="@none" respectivamente.

Sólo me llevó muuuucho tiempo para averiguarlo. (... y yo creo que es más bien unclever a Usar los valores que son diferentes de JSF!)

Me gustaría mencionar una cosa más que p:commandButton preocupaciones de Primefaces!

Cuando se utiliza un p:commandButton para la acción que hay que hacer en el servidor, no se puede utilizar type="button" porque eso es de las teclas que se utiliza para ejecutar javascript personalizada sin causar una ajax / solicitud no Ajax al servidor.

Para este propósito, se puede dispensar el atributo type (valor por defecto es "submit") o puede utilizar de forma explícita type="submit".

Esperamos que esto ayude a alguien!

se quedó atascado con este problema a mí mismo y encontró una de las causas más por este problema. Si usted no tiene métodos setter en su bean de respaldo para las propiedades que se utilizan en su * .xhtml, entonces la acción simplemente no es invocado.

Hace poco se encontró con un problema con un UICommand no invocar en una aplicación JSF 1.2 utilizando IBM caras extendidas componentes.

Yo tenía un botón de comando en una fila de una tabla de datos (la versión extendida, por lo <hx:datatable>) y el UICommand ¿no fuego de ciertas filas de la tabla (las filas que no querían fuego eran las filas superior a la fila de representación por defecto tamaño).

I tenía un componente de menú desplegable para la selección de número de filas que se vea. El valor copias de este campo estaba en RequestScope. Los datos respaldan la mesa en sí estaba en una especie de ViewScope (en realidad, temporalmente en SessionScope).

Si la fila de representación se incrementó a través del mando cuyo valor también fue obligado a rows atributo de la tabla de datos, ninguna de las filas que se muestran como resultado de este cambio podría disparar el UICommand cuando se hace clic.

La colocación de este atributo en el mismo alcance que los propios datos de mesa fija el problema.

creo que esto se alude en BalusC # 4 arriba, pero no sólo el valor de la tabla necesidad de ser vista o sesión en el ámbito sino también el atributo de controlar el número de filas que se mostrarán en esa mesa.

Yo tenía este problema, así y realmente sólo comenzó a afinar en la raíz después de la apertura de la consola web del navegador. Hasta que eso, yo era incapaz de conseguir cualquier mensaje de error (incluso con <p:messages>). La consola web mostró un código de estado HTTP 405 al volver de la <h:commandButton type="submit" action="#{myBean.submit}">.

En mi caso, tengo una mezcla de autenticación OAuth proporcionar vainilla de HttpServlet través facelets y granos que llevan a cabo mis puntos de vista de aplicación y la lógica de negocio Auth0 y JSF.

Una vez que refactorizado mi web.xml, y sacó un servlet-hombre-medio, a continuación, "mágicamente" trabajó.

En pocas palabras, el problema era que el hombre-servlet medio estaba usando RequestDispatcher.forward (...) para redirigir desde el entorno HttpServlet para el medio ambiente JSF mientras que el servlet ser llamado antes de que era reorientando con HttpServletResponse.sendRedirect (...).

Básicamente, usando sendRedirect () permitió la JSF "contenedor" para tomar el control mientras que RequestDispatcher.forward () no era obviamente.

Lo que no sé es por qué el facelet fue capaz de acceder a las propiedades de frijol, pero no los pudo establecer, y esto claramente grita para acabar con la mezcla de servlets y JSF, pero espero que esto ayude a alguien a evitar muchas horas de cabeza a-table-golpes.

Yo tenía un montón de diversión depuración de una cuestión en la acción de un <h:commandLink> en richfaces datatable negó a fuego. La tabla que se utiliza para el trabajo en algún momento, pero se detuvo sin razón aparente. Salí de piedra sin mover, sólo para descubrir que mi rich:datatable estaba usando el rowKeyConverter mal que volvió nulos que utilizan richfaces feliz como teclas de la fila. Esto impidió que mi acción <h:commandLink> de conseguir llamada.

Una posibilidad más: si el síntoma es que los primeros trabajos de invocación, pero los posteriores no lo hacen, puede que esté utilizando PrimeFaces 3.x con JSF 2.2, como se detalla aquí: no se ViewState se envía .

Me fijo mi problema con la colocación de la:

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

Para resolver;

<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>
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top