作为EL操作方法参数传递的传递请求范围变量不起作用 [英] Passing request scoped variable passed as EL action method parameter does not work

查看:136
本文介绍了作为EL操作方法参数传递的传递请求范围变量不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在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隐式EL对象.)

在服务器日志中,我已将其配置为打印方法参数,但我可以看到传入了一个空字符串,而不是预期的"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>

这是最后一个奥秘,这确实使我感到困惑,如果使用以下代码段,则可以从方法参数 FacesContext中检索"email"参数,但请记住示例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请求的应用请求值阶段期间求值的,因此这是与请求HTTP请求不同的HTTP请求.产生带有therin格式的HTML输出(并在请求中包含email参数).

<f:param>标记是在HTTP请求的呈现响应阶段评估的,该阶段需要生成带有表单的HTML输出.因此,这最终在生成的HTML输出中硬编码"(与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>
    

I am using JSF 2.2 on Glassfish 4.1.

I am trying to pass in a query parameter to as an action method argument as follows:

// 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'])}" />

(Know that param is an implicit EL object.)

In the server log I have configured it to print the method parameter, but I can see that an empty string was passed-in, not "test@email.com" as I expected.

I have confirmed that my overall configuration is working. If I replace the above snippet with the following, then "test@email.com" is output in the server log:

// Example 2. This works.

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

I have also confirmed that my use of EL implicit objects is feasible. The following snippet works if I retrieve the parameter from the FacesContext (after removing the email parameter from placeOrder's signature, of course):

// Example 3. This works.

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

And here is a final mystery, one that truly confuses me, if I use the following snippet, I can retrieve the "email" parameter from both the method parameter and the FacesContext, but recall that the method parameter wasn't retrievable in Example 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>

Can I pass in an implicit JSF EL object as an action method parameter?

And do you have an explanation for why it seems to work in Example 4, but not Example 1?

解决方案

The action attribute is evaluated during apply request values phase of the HTTP request triggered by the form submit, which is thus a different HTTP request than the one which produced the HTML output with therin the form (and having the email parameter present in the request).

The <f:param> tag is evaluated during render response phase of the HTTP request which needs to produce the HTML output with therein the form. This thus ends up "hardcoded" in the generated HTML output (on contrary to the EL method arguments in the action attribute!). When the user submits the form, this just gets passed back to the server as a plain vanilla String request parameter (which you would need to convert back if it was originally a complex type).

This has got nothing to do with whether the value is an implicit EL object or not.

That said, there are 2 other ways:

  1. Pass it as hidden input (no, not with <h:inputHidden>).

    <h:form>
        <input type="hidden" name="email" value="#{param.email}" />
        ...
    </h:form>
    

  2. Set it as property of a view scoped bean, it'll stay in bean as long as the view lives.

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

这篇关于作为EL操作方法参数传递的传递请求范围变量不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆