JSF 2:如何将包含要调用的参数的操作传递给Facelets子视图(使用ui:include和ui:param)?

时间:2011-11-04 02:21:46

标签: jsf-2 facelets el

这基本上是this answer的扩展名。

我试图在方法/动作调用中获取一个参数(对于列表/数据表中的删除按钮)。

客户端:

<ui:include src="...">
  <ui:param name="acceptButtonBean" value="#{repoHome}" />
  <ui:param name="acceptButtonAction" value="removeIndividualDocument(#{doc.id})" />
</ui:include>

子视图:

<h:commandButton value="Continue"
                 action="#{acceptButtonBean[acceptButtonAction]}" />
  ...
</h:commandButton>

但是,JSF失败了,但有一个例外:

...yadda, yadda
02:46:02,431 ERROR [stderr] (http--127.0.0.1-8080-5) Caused by: javax.el.MethodNotFoundException: /subviews/remove-doc-clink-popup.xhtml @37,98 action="#{acceptButtonBean[acceptButtonMethod]}": Method not found: com.company.project.beans.RepoHome@34b183e7.removeExternalDocument(89)()
02:46:02,431 ERROR [stderr] (http--127.0.0.1-8080-5)    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:109)
02:46:02,431 ERROR [stderr] (http--127.0.0.1-8080-5)    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
02:46:02,431 ERROR [stderr] (http--127.0.0.1-8080-5)    ... 31 more

注意

....RepoHome@34b183e7.removeExternalDocument(89)()

它无法正常工作。 JSF似乎附加括号无关紧要。

能否以不同的方式实现,但仍采用上述技术?如果是这样,怎么样?

如果没有,为什么不工作?是否指定了?这是Mojarra 2.0.x的错误吗?如果存在其他括号,我认为没有问题省略括号......

注意我不是在寻找使用f:param,f:attribute或f:setPropertyActionListener等替代解决方案。

提前致谢

1 个答案:

答案 0 :(得分:16)

这确实不是有效的EL。您不能在单个变量中混合方法名称和参数。这应该有效:

<ui:include src="...">
  <ui:param name="acceptButtonBean" value="#{repoHome}" />
  <ui:param name="acceptButtonAction" value="removeIndividualDocument" />
  <ui:param name="acceptButtonArgument" value="#{doc.id}" />
</ui:include>

<h:commandButton value="Continue"
    action="#{acceptButtonBean[acceptButtonAction](acceptButtonArgument)}" />

请注意,这与JSF并不完全相关,而是与EL有关。如果是错误或功能,您需要阅读EL规范或向EL人员报告,而不是JSF报告。 JSF在这里没有任何责任。 EL是一个完全独立的API,JSF恰巧使用它。


更新:结果证明它适用于Tomcat 7(可能是任何其他具有org.apache.el.*实现的容器),但不适用于Glassfish 3(实现com.sun.el.*) 。显示页面时,它失败如下:

Caused by: javax.el.ELException: Error Parsing: #{p1[p2](p3)}
    at com.sun.el.lang.ExpressionBuilder.createNodeInternal(ExpressionBuilder.java:174)
    at com.sun.el.lang.ExpressionBuilder.build(ExpressionBuilder.java:191)
    at com.sun.el.lang.ExpressionBuilder.createMethodExpression(ExpressionBuilder.java:242)
    at com.sun.el.ExpressionFactoryImpl.createMethodExpression(ExpressionFactoryImpl.java:81)
    at org.jboss.weld.util.el.ForwardingExpressionFactory.createMethodExpression(ForwardingExpressionFactory.java:43)
    at org.jboss.weld.el.WeldExpressionFactory.createMethodExpression(WeldExpressionFactory.java:62)
    at com.sun.faces.facelets.tag.TagAttributeImpl.getMethodExpression(TagAttributeImpl.java:222)
    ... 63 more
Caused by: com.sun.el.parser.ParseException: Encountered "(" at line 1, column 9.
Was expecting one of:
        (*snip*)

我查了EL 2.2 spec的第1.19章:

 ValueSuffix      ::= ‘.’ Identifier MethodParameters?
                    | ‘[‘ Expression ‘]’ MethodParameters?          <-- Look here
 MethodParameters ::= '(' (Expression (‘,’ Expression )* )? ')'

我非常有信心Tomcat是对的。现在是时候向Glassfish男孩报告一个错误:GLASSFISH-17628


更新2:您似乎实际上正在使用JBoss 7.我不知道它使用的Tomcat 7的哪个分支,但我可以确认我可以使用Tomcat 7.0重现您的问题。 19;按下按钮后,它失败如下:

Caused by: javax.el.MethodNotFoundException: /test.xhtml @22,62 action="#{p1[p2](p3)}": Method not found: com.example.Bean@2616aa35.submit(java.lang.String)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:109)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
    ... 24 more

成功运行时我使用的是Tomcat 7.0.22,因此它已在Tomcat 7.0.20和7.0.22之间修复。