JSF 2:如何将包含要调用的参数的动作传递给 Facelets 子视图(使用 ui:include 和 ui:param)?
Posted
技术标签:
【中文标题】JSF 2:如何将包含要调用的参数的动作传递给 Facelets 子视图(使用 ui:include 和 ui:param)?【英文标题】:JSF 2: how to pass an action including an argument to be invoked to a Facelets sub view (using ui:include and ui:param)? 【发布时间】:2011-12-21 16:46:36 【问题描述】:这基本上是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。
提前致谢
【问题讨论】:
对了,很好奇错误信息使用RepoHome#toString()
而不是RepoHome#getClass()
。
【参考方案1】:
这确实不是有效的 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 之间的某个位置。
【讨论】:
我认为这是我的第一次尝试,不幸的是它不起作用:Caused by: javax.el.MethodNotFoundException: /subviews/remove-doc-clink-popup.xhtml @37,98 action="#acceptButtonBean[acceptButtonAction](acceptButtonArgument)": Method not found: com.company.project.beans.RepoHome@2f3e7ad6.removeIndividualDocument()
BTW Eclipse 还在此处的左括号处显示警告:EL syntax error: Unexpected symbol '('.
有趣的是,Glassfish 3.1.1 (com.sun.el.*) 确实像那样混蛋,但 Tomcat 7.0.22 (org.apache.el.*) 却没有。让我看看......至于 Eclipse,我已经关闭了它的 EL 验证器,因为它是一个史诗般的失败并且一直困扰着我,所以我不能告诉任何关于这个的事情。
感谢您的帮助,现在我只需要找出 JBoss AS 7 使用的实现并报告那里的错误。您介意分享指向您的 Glassfish 错误报告的链接吗? ;-)
我做到了。但我现在意识到,这实际上并不是他完全相同的例外。让我试试旧的 Tomcat 版本...以上是关于JSF 2:如何将包含要调用的参数的动作传递给 Facelets 子视图(使用 ui:include 和 ui:param)?的主要内容,如果未能解决你的问题,请参考以下文章
使用 jquery 调用 cakephp 动作并将数组作为参数传递