I\'m curious how JSF know that I click the button, with some action and it is even possible to call an action listener with a parameter. I can imagine the server notice the
During the apply request values phase, the decode() method of all UIComponent
instances in the component tree is executed. This is where the necessary HTTP request parameters are checked and collected. In case of UIInput
components (<h:inputText>
and friends), the submitted value is been obtained. In case of UICommand
components (<h:commandButton>
and friends), the ActionEvent
is been queued.
In case of <p:commandButton>
all the magic happens in CommandButtonRenderer#decode() whom a relevant part of the source code is extracted below (line numbers are from 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 }
If you're familiar with basic HTML, you should already know that the name=value
pair of every input element and only the pressed button of the enclosing form is been sent as request parameter to the server. The PrimeFaces command button generates basically the following HTML,
<button type="submit" name="formId:buttonId" ... />
where formId:buttonId
is printed from UIComponent#getClientId()
. It's exactly this value which is been used as HTTP request parameter name (the HTTP request parameter value is the button's label, but that's not further relevant here). If you're familiar with basic Servlets, which JSF runs on top of, then you should also already know that request parameters are available by HttpServletRequest#getParameter()
, including the name=value
pair of the buttons. This allows distinguishing the pressed button.
As you see in the above decode()
method, exactly this UIComponent#getClientId()
value is also been used in order to check if the HTTP request parameter map contains the parameter name. If so, then an ActionEvent
will be queued which ultimately get invoked during invoke application phase.
As to the EL arguments, it's actually no rocket science. The whole EL expression is just executed during invoke application phase. It's not so that it's been executed during generating the HTML output of the form and then in some way passed as request parameter. No, it's just been executed during the actual invoke application phase.