【问题标题】:How does JSF process action listener?JSF 如何处理动作监听器?
【发布时间】:2013-09-21 03:15:58
【问题描述】:

我很好奇 JSF 是如何知道我点击了按钮并执行了一些操作,甚至可以使用参数调用操作侦听器。我可以想象服务器注意到状态和 EL 并调用方法。

示例 1:

<form>
   <p:commandButton actionListener="{bean.do_something(bean.info)}" />
</form>

示例 2:

<form>
     <h:datatable values=... var="myvar">
        <h:column>
           <p:commandButton actionListener="{bean.do_something(myvar.info)}" />
        </h:column>
     </h:datatable>
</form>

【问题讨论】:

    标签: jsf jsf-2 actionlistener


    【解决方案1】:

    在应用请求值阶段,执行组件树中所有UIComponent 实例的decode() 方法。这是检查和收集必要的 HTTP 请求参数的地方。如果是UIInput 组件(&lt;h:inputText&gt; 和朋友),则获取提交的值。对于UICommand 组件(&lt;h:commandButton&gt; 和朋友),ActionEvent 已排队。

    &lt;p:commandButton&gt; 的情况下,所有的魔法都发生在CommandButtonRenderer#decode() 中,source code 的相关部分在下面提取(行号来自 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  }
    

    如果您熟悉basic HTML,您应该已经知道每个输入元素的name=value 对,并且只有封闭表单的按下按钮作为请求参数发送到服务器。 PrimeFaces 命令按钮基本上生成以下 HTML,

    <button type="submit" name="formId:buttonId" ... />
    

    其中formId:buttonId 是从UIComponent#getClientId() 打印的。正是这个值被用作 HTTP 请求参数名称(HTTP 请求参数值是按钮的标签,但这里不再相关)。如果您熟悉在其上运行 JSF 的 basic Servlets,那么您还应该知道 HttpServletRequest#getParameter() 可以使用请求参数,包括 name=value 按钮对。这允许distinguishing the pressed button

    正如您在上面的decode() 方法中看到的,这个UIComponent#getClientId() 值也被用于检查HTTP 请求参数映射是否包含参数名称。如果是这样,那么ActionEvent 将被排队,最终在调用应用程序阶段被调用。

    关于 EL 论点,它实际上不是火箭科学。整个 EL 表达式只是在调用应用程序阶段执行。它不是在生成表单的 HTML 输出期间执行的,然后以某种方式作为请求参数传递。不,它只是在实际调用应用程序阶段执行的。

    【讨论】:

    • 谢谢!很好的解释!
    猜你喜欢
    • 2011-01-17
    • 1970-01-01
    • 2012-08-26
    • 2013-04-28
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 2011-06-29
    • 1970-01-01
    相关资源
    最近更新 更多