mvc - ¿Cómo procesa JSF al oyente de acción?
jsf tutorial (1)
Tengo curiosidad de saber que JSF sabe que hago clic en el botón, con algo de acción e incluso es posible llamar a un oyente de acción con un parámetro. Me imagino que el servidor notará el estado y EL y llamará a los métodos.
Ejemplo 1:
<form>
<p:commandButton actionListener="{bean.do_something(bean.info)}" />
</form>
Ejemplo 2:
<form>
<h:datatable values=... var="myvar">
<h:column>
<p:commandButton actionListener="{bean.do_something(myvar.info)}" />
</h:column>
</h:datatable>
</form>
Durante la fase Aplicar valores de solicitud, se ejecuta el método de decode()
de todas las instancias de UIComponent
en el árbol de componentes. Aquí es donde se verifican y recopilan los parámetros de solicitud HTTP necesarios. En el caso de los componentes UIInput
( <h:inputText>
y amigos), se ha obtenido el valor enviado. En el caso de los componentes de UICommand
( <h:commandButton>
y amigos), ActionEvent
se ha puesto en cola.
En el caso de <p:commandButton>
toda la magia ocurre en CommandButtonRenderer#decode()
quien se extrae una parte relevante del código fuente a continuación (los números de línea son de PrimeFaces 3.5):
34 public void decode(FacesContext context, UIComponent component) {
35 CommandButton button = (CommandButton) component;
36 if(button.isDisabled()) {
37 return;
38 }
39
40 String param = component.getClientId(context);
41 if(context.getExternalContext().getRequestParameterMap().containsKey(param)) {
42 component.queueEvent(new ActionEvent(component));
43 }
44 }
Si está familiarizado con el HTML básico , ya debe saber que el par name=value
de cada elemento de entrada y solo el botón presionado del formulario adjunto se ha enviado como parámetro de solicitud al servidor. El botón de comando PrimeFaces genera básicamente el siguiente HTML,
<button type="submit" name="formId:buttonId" ... />
donde formId:buttonId
se imprime desde UIComponent#getClientId()
. Es exactamente este valor el que se usa como nombre de parámetro de solicitud HTTP (el valor del parámetro de solicitud HTTP es la etiqueta del botón, pero eso no es más relevante aquí). Si está familiarizado con Servlets básicos , que JSF ejecuta además, también debería saber que los parámetros de solicitud están disponibles por HttpServletRequest#getParameter()
, incluido el par name=value
de los botones. Esto permite distinguir el botón presionado .
Como puede ver en el método de decode()
, este valor de UIComponent#getClientId()
también se utiliza para verificar si el mapa de parámetros de solicitud HTTP contiene el nombre del parámetro. Si es así, se pondrá en cola un ActionEvent
que finalmente se invocará durante la fase de invocación de la aplicación.
En cuanto a los argumentos EL, en realidad no es ciencia espacial. La expresión EL completa se acaba de ejecutar durante la fase de solicitud de invocación. No es así que se haya ejecutado durante la generación de la salida HTML del formulario y luego haya pasado de alguna manera como parámetro de solicitud. No, se acaba de ejecutar durante la fase de solicitud de invocación real.