传递作为 EL 操作方法参数传递的请求范围变量不起作用

Passing request scoped variable passed as EL action method parameter does not work

我在 Glassfish 4.1 上使用 JSF 2.2。

我正在尝试将查询参数作为操作方法参数传递给,如下所示:

// Example 1. This does not work.

// at url http://localhost:8080/app/order.xhtml?email=test@email.com

<p:commandButton value="Place order" action="#{orderManager.placeOrder(param['email'])}" />

(知道param是一个implicit EL object。)

在服务器日志中,我已将其配置为打印方法参数,但我可以看到传入了一个空字符串,而不是我预期的"test@email.com"。

我已确认我的整体配置正常。如果我用以下代码替换上面的代码片段,那么 "test@email.com" 会在服务器日志中输出:

// Example 2. This works.

<p:commandButton value="Place order" action="#{orderManager.placeOrder('test@email.com')}" />

我也确认了我使用 EL 隐式对象是可行的。如果我从 FacesContext 中检索参数(当然是在从 placeOrder 的签名中删除电子邮件参数之后),则以下代码片段有效:

// Example 3. This works.

<p:commandButton value="Place order" action="#{orderManager.placeOrder()}" >
  <f:param name="email" value="#{param['email']}"/>
</p:commandButton>

这是最后一个谜,一个真正让我感到困惑的谜,如果我使用以下代码片段,我可以从方法参数 和 [=37= 中检索 "email" 参数] FacesContext,但请记住,在示例 1 中无法检索方法参数!

// Example 4. This works, and BOTH parameters are retrievable!

<p:commandButton value="Place order" action="#{orderManager.placeOrder(param['email'])}" >
  <f:param name="email" value="#{param['email']}"/>
</p:commandButton>

我可以传入隐式 JSF EL 对象作为操作方法参数吗?

您是否解释了为什么它在示例 4 中有效,但在示例 1 中无效?

action 属性在表单提交触发的 HTTP 请求的应用请求值阶段被评估,因此这是一个不同于使用 therin 产生 HTML 输出的 HTTP 请求表单(并且请求中存在 email 参数)。

<f:param> 标签在 HTTP 请求的呈现响应阶段进行评估,需要生成 HTML 输出,其中包含表单。因此,这在生成的 HTML 输出中以 "hardcoded" 结束(与 action 属性中的 EL 方法参数相反!)。当用户提交表单时,这只是作为普通 String 请求参数传回服务器(如果它最初是复杂类型,则需要将其转换回来)。

这与该值是否为隐式 EL 对象无关。

也就是说,还有其他两种方法:

  1. 将其作为隐藏输入传递(不,不使用 <h:inputHidden>)。

    <h:form>
        <input type="hidden" name="email" value="#{param.email}" />
        ...
    </h:form>
    
  2. 将其设置为视图作用域 bean 的 属性,只要视图存在,它就会保留在 bean 中。

    <f:metadata>
        <f:viewParam name="email" value="#{viewScopedBean.email}" />
    </f:metadata>